套接字的缓冲 Reader 永远不会准备好

Buffered Reader for a socket is never ready

为了完全透明,这是一项作业。

还有更多工作要做,但目前我只想获得以下内容:

  1. 节点 A 从文本文件中读入
  2. 节点 A 使用套接字向节点 B 发送文本文件(减去第一行)
  3. 节点 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 上查找函数,您可以看到执行的代码:

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/io/BufferedReader.java#BufferedReader.ready%28%29

就绪线程仅意味着它不会阻塞,这在您要确保您的线程不会被占用时很有用,但不会真正告诉您是否有缓冲区。

您想做的是执行 readline,作为阻塞调用,直到数据被消耗。如果您不希望它阻塞您当前的线程,则分拆一个特定于此读取的可以阻塞的新消费者线程。

此外,请确保您使用关闭的套接字或刷新来结束发送通信,以在完成时向消费流指示。而且你只需要在每个 open/close 会话中接受一次套接字。