我的问题与这篇文章类似。但是我不会发送数据包长度而不是最后一个0字节。 Most efficient way to read in a tcp stream in Java
所以我想知道我将如何编写可以编写的内容。
目前我只是使用
this.socketIn = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
String line = this.socketIn.readLine();
如果在发送数据包时发送数据包,它将计算尚未作为完全读取线路到达的数据包,但它不完整并且会弄乱整个协议。
在我的协议中,每个数据包以0字节(0x00)结束,以确定单个数据包的结束,如果数据包最终合并/堆叠在一起。
所以我要做的就是继续读取套接字流,直到达到0x00表示数据包已经完全制作并准备好进行处理..当然还有某种安全性(超时是最好的我相信)确定数据包是垃圾,因为它没有在特定时间范围内以0字节结束,比如5秒。
我该怎么做呢?
P.S> 我没有使用NIO框架,只是每个连接套接字的常规线程,我不想切换到NIO,因为很难用完全不同的全局线程注入数据,该线程处理更新并向随机用户发送特定更新(不是广播)。
这是我到目前为止所尝试的内容。
String line = "";
int read;
long timeOut = System.currentTimeMillis();
while(true) {
read = this.socketIn.read();
if (read == -1 || read == 0 || (System.currentTimeMillis()-timeOut) > 5000)
break;
line += read
}
答案 0 :(得分:5)
这是使用setSocketTimeout处理“慢客户端/拒绝服务”场景的草图。
this.socket.setSoTimeout(5000);
BufferedReader br = new BufferedReader(
new InputStreamReader(this.socket.getInputStream()));
StringBuilder sb = new StringBuilder();
try {
int ch ;
while ((ch == br.read()) != -1) {
if (ch == 0) {
String message = sb.toString();
// process message
sb.setLength(0);
} else {
sb.append((char) ch);
}
}
} catch (InterruptedIOException ex) {
System.err.println("timeout!");
...
} finally {
br.close();
}
我认为通过创建第二个线程来实现(残酷的)套接字超时,如果它检测到读取线程没有获取任何数据,则可以在套接字对象上调用socket.close()
。但考虑到更简单的setSoTimeout()
方法,这是一种重量级方法。
答案 1 :(得分:2)
InputStreamReader isr = new InputStreamReader(socket.getInputStream());
BufferedReader in = new BufferedReader(isr);
String line = "";
String response = "";
while ((line = in.readLine()) != null) {
System.out.println(line);
response = response + line + "\n";
if (in.ready() == false) {
break;
}
}
技巧是属于BufferedReader的ready函数。你需要检查它是否准备就绪,如果不是刚刚离开循环。
答案 2 :(得分:0)
我应该使用StringBuilder吗?或者像EJP写的那样建立我自己的。哪个更快?
String line = "";
int read;
//long timeOut = System.currentTimeMillis();
this.socket.setSoTimeout(5000);
while(this.socket.isConnected()) {
read = this.socketIn.read();
if (read == -1)
throw new IOException("Insufficient data / timeout)");
else if(read == 0)
break;
line += (char)(read & 0xFF);
}