代码之家  ›  专栏  ›  技术社区  ›  SSpoke

如何读取java流直到达到某个字节

  •  3
  • SSpoke  · 技术社区  · 15 年前

    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();
    

    如果数据包是被发送,而你是垃圾邮件的数据包,它将计数的数据包尚未到达作为一个完全读取线,但它是不完整的,并扰乱了整个协议。

    所以我真正要做的是一直读取套接字流,直到到达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
        }
    
    3 回复  |  直到 8 年前
        1
  •  6
  •   Stephen C    15 年前

    下面是一个使用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() 接近。

        2
  •  2
  •   Neil    13 年前
    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函数。你需要检查它是否准备好了,如果不是的话,就从循环中出来。

        3
  •  0
  •   SSpoke    15 年前

                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);
                }