如何读取java流直到达到特定字节
我的问题与这篇文章类似。但我不发送数据包长度,而是在末尾发送 0 字节。 读取 TCP 流的最有效方法Java
所以我想知道如何编写这样的代码。
目前,我只是使用“
this.socketIn = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
String line = this.socketIn.readLine();
如果在您向数据包发送垃圾邮件时正在发送数据包”,它会将尚未到达的数据包视为完全读取的行,但它不完整并且会弄乱整个协议。
在我的协议中,每个数据包都以 0 字节 (0x00) 结尾,以确定单个数据包的结尾(如果数据包最终合并/堆叠在一起)。
所以我真正想做的是继续读取套接字流,直到达到 0x00 为止,这表明数据包已完全制作并准备好进行处理..当然还有某种安全性(我认为超时是最好的)来确定该数据包是垃圾数据包,因为它在特定时间范围(例如 5 秒)内没有以 0 字节结束。
我该怎么做呢?
PS> 我没有使用 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
}
My question is similar to this post. But I don't send packet length rather a 0 byte at end.
Most efficient way to read in a tcp stream in Java
So I'm wondering how would I code something that would.
At the moment I just use
this.socketIn = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
String line = this.socketIn.readLine();
If packet is getting sent while you are spamming the packet it's going to count the packet which hasn't arrived yet as a fully read Line, yet it's incomplete and messes up the whole protocol.
In my protocol each packet is ended with a 0 byte (0x00) to determine the end of a single packet if in case packets end up merged/stacked together.
So what I'm trying to do really is keep reading the socket stream until a 0x00 is reached to indicate the packet is fully crafted and ready for processing.. and of course some kind of security (a timeout is best I believe) to determine the packet is junk as it's not ended in a 0 byte in a specific time frame lets say 5 seconds.
How would I go about doing this?
P.S>
I'm not using NIO framework but just a regular thread per connection socket and I don't want to switch to NIO as it's very difficult to inject data with a completely different global thread that processes updates and sends specific updates to random users (not broadcast).
Here is what I tried so far.
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
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
下面是使用 setSocketTimeout 处理“缓慢的客户端/拒绝服务”场景的草图。
我认为还可以通过创建第二个线程来实现(残酷的)套接字超时,如果它检测到读取线程没有获取任何数据,则该线程在套接字对象上调用
socket.close()
。但考虑到更简单的setSoTimeout()
方法,这是一个重量级方法。Here's a sketch using setSocketTimeout to deal with the "slow client / denial of service" scenario.
I think it is also possible to implement a (brutal) socket timeout by creating a second thread that calls
socket.close()
on the socket object if it detects that the reading thread is not getting any data. But that's a heavyweight approach, given the simplersetSoTimeout()
approach.诀窍是属于 BufferedReader 的 Ready 函数。您需要检查它是否准备好,如果没有就退出循环。
The trick is the ready function that belongs to the BufferedReader. You need to check if it's ready, if not just get out of the loop.
我应该使用 StringBuilder 吗?或者按照 EJP 编写的方式构建我自己的。哪个更快?
Should I use StringBuilder? or build my own as EJP wrote. which is faster?