socket如何读取java流,直到达到某个字节
我的问题与这篇文章类似。但我不发送数据包长度,而是在末尾发送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)结尾,以确定单个数据包的结尾,以防数据包合并/堆叠在一起
因此,我真正要做的是继续读取socket流,直到达到0x00,以指示数据包已完全构建并准备好进行处理。。当然还有某种安全性(我认为超时是最好的)来确定数据包是垃圾,因为它在特定的时间范围内没有以0字节结束,比如说5秒
我该怎么做呢
p.S>; 我没有使用NIO框架,只是每个连接socket使用一个常规线程,我不想切换到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
}
# 1 楼答案
下面是一个使用setSocketTimeout处理“慢速客户端/拒绝服务”场景的示意图
我认为还可以通过创建第二个线程来实现(残酷的)套接字超时,如果它检测到读取线程没有获取任何数据,则在套接字对象上调用
socket.close()
。但考虑到更简单的setSoTimeout()
方法,这是一种重量级方法# 2 楼答案
诀窍是属于BufferedReader的ready函数。你需要检查它是否准备好了,如果不是的话,就退出循环
# 3 楼答案
我应该使用StringBuilder吗?或者像EJP写的那样构建我自己的。哪个更快