[英]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.