java - 如何读取java流直到达到特定字节

标签 java sockets stream packet

我的问题与这篇文章类似。但我不发送数据包长度,而是在末尾发送 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();

如果在您向数据包发送垃圾邮件时正在发送数据包,则会将尚未到达的数据包视为完全读取的行,但它是不完整的并且会扰乱整个协议(protocol)。

在我的协议(protocol)中,每个数据包都以 0 字节 (0x00) 结尾,以确定单个数据包的结尾(如果数据包最终合并/堆叠在一起)。

所以我真正想做的是继续读取套接字流,直到达到 0x00 为止,这表明数据包已完全制作并准备好进行处理..当然还有某种安全性(我认为超时是最好的)来确定数据包是垃圾数据包,因为它在特定时间范围内没有以 0 字节结束(假设为 5 秒)。

我该如何去做呢?

PS> 我没有使用 NIO 框架,而只是每个连接套接字使用一个常规线程,并且我不想切换到 NIO,因为使用完全不同的全局线程注入(inject)数据非常困难,该线程处理更新并向随机用户发送特定更新(不是广播)。

这是我迄今为止尝试过的。

    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
    }

最佳答案

这是使用 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() 方法,这是一种重量级方法。

关于java - 如何读取java流直到达到特定字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3498126/

相关文章:

c - 我的 c 套接字程序在成功执行命令后在命令上吐出垃圾,不知道为什么

c - C 中使用多个分离线程的内存泄漏

C# 更改上传图像的 dpi

c# - 分层应用程序 : Store file in filestream in the database

JAVA 对象/字符串方法重载

java - 我如何限制 Jetty 接受的连接数?

java - 解决JAVA中一个URL请求的NullPointerException

java - 多线程环境中的 ACID 问题

ios - 在 NSRunLoop 上调度流

java - lush() 不会刷新 Process OutputStream