繁体   English   中英

TCP如何用Java发送/接收实时大数据包?

[英]TCP how to send/receive real-time large packets in Java?

我正在运行此TCP服务器,因为UDP服务器可以接受大数据包,但是ISP阻止了我的UDP数据包,即使我有公共IP和静态服务也是如此。 但是现在决定将其更改为TCP,但是我现在有一个很大的堆栈可以替换为UDP到TCP。

这是正在运行的服务器,但是它不会立即收到一个大数据包,我如何将其增加到无限制或最大大小等?

1)有什么办法吗?

public void run() 
{
    while(true) 
    {
        byte[] buf=new byte[5024]; <<< not helping!!
        int bytes_read = 0;
        try {                                
            bytes_read = sockInput.read(buf, 0, buf.length);                  
            String data = null;
            data = new String(buf, 0, bytes_read);                   
            System.out.println("[TCP]: incomeing data: " +  bytes_read + " bytes, data=" +data);
     }
 }

2)有什么办法吗?

public TCPHandler(Socket sock) throws IOException 
{
    sock.setReceiveBufferSize(10*1024 +1024); //<<<<< not helping !!!
    sock.setSendBufferSize(10*1024+1024);
    this.sock = sock;
    sockInput = sock.getInputStream();
    sockOutput = sock.getOutputStream();
    this.myThread = new Thread(this);
}

没有人可以让我处理很多事情,以便可以从UDP切换到TCP。 有任何想法吗!!

TCP和UDP不同。 TCP不是基于数据包的协议,而是基于流的协议。 您的数据将按顺序到达且未损坏,但不一定会立即全部到达。

您应该做的是在每个集合“数据包”前面加上一个长度。 接收数据时,请先读取长度值,然后继续从套接字读取块,直到获得所需的数据量为止。

您不必关心TCP如何将消息拆分为数据包,以及必须阅读多少次才能获得完整的消息。 只需读取直到到达消息末尾,然后返回消息的所有字节即可。

知道何时完全读取消息取决于您的协议。 您可以选择每个连接仅发送一条消息,或者可以在消息之前发送消息的长度,或者使用一些标记字节。

请注意,不要在未指定编码的情况下使用new String(byte[]) (并且在调用String.getBytes()时使用相同的编码),尤其是当您从一台计算机传输到另一台计算机时,因为两台计算机的默认设置可能不同编码。

您遇到的麻烦是InputStreams的工作方式。 当您调用read(buf,offset,length)时,它并不总是每次都读取长度字节。 它只是读取InputStream上的available(),并返回读取的字节数。 因此,您需要继续调用read,直到您实际读取了长度字节。

int len = 0;
int expectedLength = sockInput.readInt();
byte[] buf = new byte[ expectedLength ];
while( len != buf.length ) {
   len += sockInput.read( buf, len, buf.length );
}

// now you have a buffer with expectedLength data in it.

您还可以通过包装您的代码来查看使用DataInputStream.readFully()

DataInputStream ds = new DataInputStream( sock.getInputStream() );
ds.readFully( buf, 0, buf.length );

http://docs.oracle.com/javase/6/docs/api/java/io/DataInputStream.html

但是,如果您真的只是在使用String,则应该这样做:

Reader reader = new InputStreamReader( sockInput.getInputStream(), "UTF-8" );

read(char [],offset,length)的规则与read(byte [],offset,length)相同

TCP是可以获取一部分字节流,一个或多个消息是一次读取。 如果UDP数据包超过532个字节,则该数据包可能会被分解,因此您也有同样的潜在问题。

编码消息的一种简单方法是先发送长度。

 final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
 final DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

 public void writeMessage(String text) {
    out.writeUTF(text);
 }

 public String readMessage() {
    return in.readUTF();
 }

读/写UTF首先发送长度,然后发送内容

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM