简体   繁体   English

阅读Socket中可用的内容而不会阻塞

[英]Reading what's available from Socket without blocking

I am working on a server which reads data sent by the client, but the size is not known neither can I change the client to send the size. 我正在服务器上读取客户端发送的数据,但是大小不知道我也不能更改客户端发送大小。

I want to read the data from client till it blocks and waits for server's response. 我想从客户端读取数据,直到它阻塞并等待服务器的响应。 I tried using available() , it works sometimes but sometimes it just returns zero even when there's some data in stream. 我尝试使用available() ,它有时会工作,但有时它只返回零,即使流中有一些数据。

while((len = in.available()) != 0)
    in.read(b,0,len);

Is there any way to do this in Java? 有没有办法在Java中这样做? I'm aware of asynchronous methods, but have never tried that, so if someone can provide a short example. 我知道异步方法,但从未尝试过,所以如果有人可以提供一个简短的例子。

Using available() is the only way to do it without resorting to asynchronous methods. 使用available()是唯一的方法,无需借助异步方法。

You don't really need to rely on the value returned by available() ; 你真的不需要依赖available()返回的值; just check that there is "some" data available to make sure that read will not block. 只需检查是否有“某些”数据可用,以确保read不会阻止。 You must, however, check the value returned by read (the actual number of bytes read into the array): 但是,您必须检查read返回的值(读入数组的实际字节数):

// Process all data currently available
while (in.available() != 0)
{
    int nb = in.read(b);
    // Process nb bytes
}

Note that available returning 0 does not mean that the end of the data was reached -- it merely means that there is no data available for immediate consumption (data may become available in the next millisecond). 请注意, available返回0并不意味着已到达数据的末尾 - 它仅意味着没有可用于立即消费的数据(数据可能在下一毫秒内变得可用)。 Thus you'll need to have some other mechanism in order for the server to know that the client will not send any more data and is waiting for a response instead. 因此,您需要具有一些其他机制,以便服务器知道客户端将不再发送任何数据并且正在等待响应。

InputStream JavaDocs for the method available() clearly states that available()方法的InputStream JavaDocs available()清楚地说明了这一点

Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. 请注意,虽然InputStream的某些实现将返回流中的总字节数,但许多实现不会。 It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream. 使用此方法的返回值来分配用于保存此流中所有数据的缓冲区绝对不正确。

You should instead try the read() method to read data into a fixed size buffer allocated with, say 4096 bytes. 您应该尝试使用read()方法将数据读入分配有4096字节的固定大小的缓冲区。

I tried a lot of solutions but the only one I found which wasn't blocking execution was: 我尝试了很多解决方案但是我找到的唯一一个没有阻止执行的解决方案是:

BufferedReader inStream = new BufferedReader(new InputStreamReader(yourInputStream));
String line;
while(inStream.ready() && (line = inStream.readLine()) != null) {
    System.out.println(line);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM