[英]BufferedReader never ready (Socket programming in Java)
I have socket already declared socket like this: 我有套接字已经声明套接字像这样:
serverAddr = InetAddress.getByName(this.ip);
socket = new Socket(serverAddr, port);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
however, the following doesn't work. 但是,以下不起作用。
in.ready()
always returns false and if removed the program will freeze at String message = in.readLine();
in.ready()
总是返回false,如果删除,程序将冻结在String message = in.readLine();
private void receive() {
try {
InputStreamReader isr = new InputStreamReader(socket.getInputStream());
System.out.println(isr.getEncoding());
BufferedReader in = new BufferedReader(isr);
if (in.ready()) {
String message = in.readLine();
if (message != null) {
if (listener != null) {
listener.receiveMessage(ip, message);
} else {
print("Client recieved: " + message);//
}
}
}
in.close();
} catch (Exception e) {
print("Error with input stream: " + e);
disconnect();
}
}
How could i solve this? 我怎么能解决这个问题?
EDIT: 编辑:
This is how sending looks like in my server class: out.println(message); 这就是我的服务器类中的发送方式:out.println(message); out.flush();
了out.flush(); This happens in a loop whenever i've put something in message.
每当我在消息中放入某些内容时,就会发生这种情况。 out is closed after this loop.
在此循环后关闭。
You shouldn't be using ready()
like this. 你不应该像这样使用
ready()
。 The javadoc says this: javadoc说:
"Returns: True if the next read() is guaranteed not to block for input, false otherwise. Note that returning false does not guarantee that the next read will block. "
“返回:如果保证下一个read()不阻止输入,则返回true,否则返回false。注意,返回false并不能保证下一次读取将阻塞。”
Your code is implicitly assuming that ready() -> false
means that the next read
will block. 您的代码隐式假设
ready() -> false
表示下一次read
将阻塞。 In actual fact, it means the next read
might or might not block. 实际上,这意味着下一次
read
可能会阻止也可能不会阻塞。
As @EJP says ... just do the read
call. 正如@EJP所说......只是做
read
通话。
What could i do to prevent a block though?
我该怎么做才能防止阻塞呢? The client will be unable to send anything if it's blocked
如果被阻止,客户端将无法发送任何内容
If blocking in read is a problem for your application, either use a separate thread to do the reading, or change your code to use NIO channel selectors. 如果读取中的阻塞是应用程序的问题,请使用单独的线程进行读取,或者更改代码以使用NIO通道选择器。
Just remove the in.ready() test. 只需删除in.ready()测试即可。 It isn't helping you.
它没有帮助你。 readLine() will block until there is data available.
readLine()将阻塞,直到有可用数据。 What else were you planning to do if no data has arrived yet?
如果还没有数据到达,你还打算做什么?
There are 3 things that come to my mind: 我想到了三件事:
receive
call, and wrapping it into a BufferedReader
. receive
调用中重新打开输入流,并将其包装到BufferedReader
。 This might read more than a single line into the buffer, and after finishing (closing it), the remaining buffered bytes will no longer be available for subsequent receive
calls receive
调用 flush()
and close()
calls. flush()
和close()
调用,但有时并不是所有数据都被另一方接收。 Maybe this is also an issue in your situation Edit: 编辑:
Smiply keeping the in
reference outside of the receive
method will not fully solve your problem. Smiply保持
in
该外部参考receive
方法不能完全解决你的问题。 You should use a while loop for reading all buffered messages and call the listener for everyone, eg: 您应该使用while循环来读取所有缓冲的消息并为每个人调用侦听器,例如:
if (in.ready()) {
String message;
while ((message = in.readLine()) != null) {
// ...
}
}
But watch out as the last line might be a partially read message (eg 3 and 1/2 messages were buffered). 但请注意,最后一行可能是部分读取的消息(例如,3和1/2消息被缓冲)。 If this is an issue, you could read the messages char-by-char for determining when a line ends, and use a
PushbackReader
for putting back incomplete messages. 如果这是一个问题,您可以读取消息char-by-char以确定行何时结束,并使用
PushbackReader
来放回不完整的消息。
您可能需要调用out.flush()
来刷新BufferedWriter
任何内容
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.