套接字的缓冲 Reader 永远不会准备好
Buffered Reader for a socket is never ready
为了完全透明,这是一项作业。
还有更多工作要做,但目前我只想获得以下内容:
- 节点 A 从文本文件中读入
- 节点 A 使用套接字向节点 B 发送文本文件(减去第一行)
- 节点 B 从所述套接字读入,并将其打印到控制台
但是,目前看来,信息没有被发送,或者节点 B 没有正确读取。
在我的主 class 中,我这样设置节点:
NodeA nodeA = new NodeA();
NodeB nodeB = new NodeB();
new Thread(nodeA).start();
new Thread(nodeB).start();
在节点A中,我这样做:
//Open a socket for talking with NodeB
Socket mySocket = new Socket(InetAddress.getLocalHost(), portNum);
//Set up the socket's output
PrintWriter out = new PrintWriter(mySocket.getOutputStream(), true);
//Loop through the lines of the confA file, writing them to the socket
String line = bufferedReader.readLine();
while (line != null)
{
//Write the line to the socket, get the next line
out.println(line); //updated to println, this flushes and fixes another problem
out.flush();
line = bufferedReader.readLine();
}
//Close the socket
mySocket.close();
请注意,节点 A 的循环工作正常。当我用 print 语句测试时,它不会永远循环,并且会遍历预期的文本行。
然后,在节点 B 端:已更新以显示当前节点 B 代码
//Open the socket
ServerSocket mySocket = new ServerSocket(portNum);
Socket connectionSocket = mySocket.accept();
//Set up a reader on the socket to get what's coming from it
BufferedReader in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
String line = in.readLine(); //hang occurs here
while(line != null) {
System.out.println(line);
line = in.readLine();;
}
然而,in.ready() 永远不会成立。我试过使用 while 循环等待它发生,但它从未发生过。
我真的不知道为什么。我不知道我是否正确设置了套接字,是否正确设置了服务器,是否正确监听等等
我只是觉得将 B 变成一个正在侦听 A 的服务器是最有意义的。我希望这是对的。它看起来与我在 SO 上看到的一些其他示例相似。
感谢您提供的所有帮助。我对套接字、端口、监听等非常不熟悉,所以如果我一开始不理解你的建议,请原谅我。我会尽力去理解它。
我没有添加整个代码,希望能使其更具可读性并清楚问题可能出在哪里,但如果您需要更多信息,请随时询问,我会尽力提供。
服务器必须先从ServerSocket中获取到客户端的Socket。
connectionSocket = mySocket.accept();
服务器线程将处于休眠状态,直到客户端使其接受 connectionSocket。
那么就可以从connectionSocket中读取了。 ready
不需要。
因为这是作业,剩下的就交给你了。
顺便说一句,典型的服务器会做:
for (;;) {
Socket socket = serverSocket.accept();
... pass the socket to a thread from a pool of threads
}
我认为问题在于就绪只是意味着如果您调用读取,它不会阻塞。如果您在 grepcode 上查找函数,您可以看到执行的代码:
就绪线程仅意味着它不会阻塞,这在您要确保您的线程不会被占用时很有用,但不会真正告诉您是否有缓冲区。
您想做的是执行 readline,作为阻塞调用,直到数据被消耗。如果您不希望它阻塞您当前的线程,则分拆一个特定于此读取的可以阻塞的新消费者线程。
此外,请确保您使用关闭的套接字或刷新来结束发送通信,以在完成时向消费流指示。而且你只需要在每个 open/close 会话中接受一次套接字。
为了完全透明,这是一项作业。
还有更多工作要做,但目前我只想获得以下内容:
- 节点 A 从文本文件中读入
- 节点 A 使用套接字向节点 B 发送文本文件(减去第一行)
- 节点 B 从所述套接字读入,并将其打印到控制台
但是,目前看来,信息没有被发送,或者节点 B 没有正确读取。
在我的主 class 中,我这样设置节点:
NodeA nodeA = new NodeA();
NodeB nodeB = new NodeB();
new Thread(nodeA).start();
new Thread(nodeB).start();
在节点A中,我这样做:
//Open a socket for talking with NodeB
Socket mySocket = new Socket(InetAddress.getLocalHost(), portNum);
//Set up the socket's output
PrintWriter out = new PrintWriter(mySocket.getOutputStream(), true);
//Loop through the lines of the confA file, writing them to the socket
String line = bufferedReader.readLine();
while (line != null)
{
//Write the line to the socket, get the next line
out.println(line); //updated to println, this flushes and fixes another problem
out.flush();
line = bufferedReader.readLine();
}
//Close the socket
mySocket.close();
请注意,节点 A 的循环工作正常。当我用 print 语句测试时,它不会永远循环,并且会遍历预期的文本行。
然后,在节点 B 端:已更新以显示当前节点 B 代码
//Open the socket
ServerSocket mySocket = new ServerSocket(portNum);
Socket connectionSocket = mySocket.accept();
//Set up a reader on the socket to get what's coming from it
BufferedReader in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
String line = in.readLine(); //hang occurs here
while(line != null) {
System.out.println(line);
line = in.readLine();;
}
然而,in.ready() 永远不会成立。我试过使用 while 循环等待它发生,但它从未发生过。
我真的不知道为什么。我不知道我是否正确设置了套接字,是否正确设置了服务器,是否正确监听等等
我只是觉得将 B 变成一个正在侦听 A 的服务器是最有意义的。我希望这是对的。它看起来与我在 SO 上看到的一些其他示例相似。
感谢您提供的所有帮助。我对套接字、端口、监听等非常不熟悉,所以如果我一开始不理解你的建议,请原谅我。我会尽力去理解它。
我没有添加整个代码,希望能使其更具可读性并清楚问题可能出在哪里,但如果您需要更多信息,请随时询问,我会尽力提供。
服务器必须先从ServerSocket中获取到客户端的Socket。
connectionSocket = mySocket.accept();
服务器线程将处于休眠状态,直到客户端使其接受 connectionSocket。
那么就可以从connectionSocket中读取了。 ready
不需要。
因为这是作业,剩下的就交给你了。
顺便说一句,典型的服务器会做:
for (;;) {
Socket socket = serverSocket.accept();
... pass the socket to a thread from a pool of threads
}
我认为问题在于就绪只是意味着如果您调用读取,它不会阻塞。如果您在 grepcode 上查找函数,您可以看到执行的代码:
就绪线程仅意味着它不会阻塞,这在您要确保您的线程不会被占用时很有用,但不会真正告诉您是否有缓冲区。
您想做的是执行 readline,作为阻塞调用,直到数据被消耗。如果您不希望它阻塞您当前的线程,则分拆一个特定于此读取的可以阻塞的新消费者线程。
此外,请确保您使用关闭的套接字或刷新来结束发送通信,以在完成时向消费流指示。而且你只需要在每个 open/close 会话中接受一次套接字。