我已经将套接字声明为套接字如下:
serverAddr = InetAddress.getByName(this.ip);
socket = new Socket(serverAddr, port);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
但是,以下内容不起作用。 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();
}
}
我怎么能解决这个问题?
编辑:
这就是我的服务器类中的发送方式: 通过out.println(消息); 了out.flush(); 每当我在消息中放入某些内容时,就会发生这种情况。在这个循环之后关闭。
答案 0 :(得分:4)
您不应该像这样使用ready()
。 javadoc说明了这一点:
“返回:如果保证下一个read()不阻止输入,则返回true,否则返回false。注意,返回false并不能保证下一次读取将阻塞。”
您的代码隐含地假设ready() -> false
表示下一个read
将阻止。实际上,这意味着下一个read
可能会或可能不会阻止。
正如@EJP所说......只需拨打read
电话。
我该怎么办才能阻止阻挡?如果被阻止,客户端将无法发送任何内容
如果读取中的阻塞是您的应用程序的问题,请使用单独的线程进行读取,或更改代码以使用NIO通道选择器。
答案 1 :(得分:2)
只需删除in.ready()测试即可。它没有帮助你。 readLine()将阻塞,直到有可用数据。如果还没有数据到达,你打算做什么?
答案 2 :(得分:1)
我想到了三件事:
receive
调用中重新打开输入流,并将其包装到BufferedReader
中。这可能会在缓冲区中读取多行,并且在完成(关闭它)之后,剩余的缓冲字节将不再可用于后续的receive
调用flush()
和close()
来电。在你的情况下,这也是一个问题 修改强>
将in
引用保留在receive
方法之外,并不能完全解决您的问题。您应该使用while循环来读取所有缓冲的消息并为每个人调用侦听器,例如:
if (in.ready()) {
String message;
while ((message = in.readLine()) != null) {
// ...
}
}
但请注意,最后一行可能是部分阅读的消息(例如,3和1/2消息被缓冲)。如果这是一个问题,您可以读取消息char-by-char以确定行何时结束,并使用PushbackReader
来放回不完整的消息。
答案 3 :(得分:0)
您可能需要致电out.flush()
以清除BufferedWriter