Java 在不阻塞的情况下从 Socket 读取可用内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8277390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-15 00:34:29  来源:igfitidea点击:

Reading what's available from Socket without blocking

java

提问by vidit

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? I'm aware of asynchronous methods, but have never tried that, so if someone can provide a short example.

有没有办法在Java中做到这一点?我知道异步方法,但从未尝试过,所以如果有人可以提供一个简短的例子。

采纳答案by Grodriguez

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(); just check that there is "some" data available to make sure that readwill not block. You must, however, check the value returned by read(the actual number of bytes read into the array):

你真的不需要依赖available();返回的值。只需检查是否有“一些”数据可用以确保read不会阻塞。但是,您必须检查由read(读入数组的实际字节数)返回的值:

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

Note that availablereturning 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). 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.

请注意,available返回 0 并不意味着已到达数据末尾——它仅意味着没有可立即使用的数据(数据可能在下一毫秒内变得可用)。因此,您需要有一些其他机制,以便服务器知道客户端将不再发送任何数据,而是在等待响应。

回答by asgs

InputStreamJavaDocsfor the method available()clearly states that

InputStream该方法的 JavaDocsavailable()明确指出

Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.

请注意,虽然 InputStream 的某些实现会返回流中的总字节数,但许多不会。使用此方法的返回值来分配用于保存此流中所有数据的缓冲区永远是不正确的。

You should instead try the read()method to read data into a fixed size buffer allocated with, say 4096 bytes.

您应该尝试将read()数据读入分配有固定大小的缓冲区的方法,例如 4096 字节。

回答by vovahost

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