【问题标题】:Java InputStream wait for data.Java InputStream 等待数据。
【发布时间】:2012-03-28 20:03:21
【问题描述】:

我正在开发服务器-客户端应用程序,但在等待输入流上的输入数据时遇到问题。

我有专门用于读取输入数据的线程。目前它使用 while 循环来保持直到数据可用。 (NB协议如下:发送数据包的大小,比如N,作为int然后发送N字节)。

public void run(){
    //some initialization
    InputStream inStream = sock.getInputStream();
    byte[] packetData;
    //some more stuff
    while(!interrupted){
        while(inStream.available()==0);
        packetData = new byte[inStream.read()];
        while(inStream.available()<packetData.length);
        inStream.read(packetData,0,packetData.length);
        //send packet for procession in other thread
    }
}

它可以工作,但通过 while 循环阻塞线程是 IMO 一个坏主意。我可以使用 Thread.sleep(X) 来防止资源被循环不断消耗,但肯定有更好的方法。

我也不能依赖 InputStream.read 来阻塞线程,因为服务器可能会延迟发送部分数据。我尝试过,但总是导致意外行为。

我会很感激任何想法 :)

【问题讨论】:

  • InputStream.read 在数据不可用时已经阻塞。所以放弃available 方法。

标签: java sockets stream


【解决方案1】:

你可以使用 DataInputStream.readFully()

DataInputStream in = new DataInputStream(sock.getInputStream());
//some more stuff
while(!interrupted) {
    // readInt allows lengths of up to 2 GB instead of limited to 127 bytes.
    byte[] packetData = new byte[in.readInt()];
    in.readFully(packetData);
    //send packet for procession in other thread
}

我更喜欢使用支持可重用缓冲区的阻塞 NIO。

SocketChannel sc = 
ByteBuffer bb = ByteBuffer.allocateDirect(1024 *1024); // off heap memory.

while(!Thread.currentThread.isInterrupted()) {
     readLength(bb, 4);
     int length = bb.getInt(0);
     if (length > bb.capacity()) 
         bb = ByteBuffer.allocateDirect(length);
     readLength(bb, length);
     bb.flip();
     // process buffer.
}



static void readLength(ByteBuffer bb, int length) throws EOFException {
     bb.clear();
     bb.limit(length);
     while(bb.remaining() > 0 && sc.read(bb) > 0);
     if (bb.remaining() > 0) throw new EOFException();
}

【讨论】:

    【解决方案2】:

    正如 UmNyobe 所说,available() 应该在您想要阻止时使用,因为默认行为是阻止。

    只需使用普通的read 来读取可用的任何内容,但只有在缓冲区中有packetData.length 字节后发送数据包以在其他线程中处理...

    【讨论】:

    • 谢谢...拯救了我的一天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 2011-11-15
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 2021-07-01
    相关资源
    最近更新 更多