简体   繁体   English

套接字的缓冲读取器从未准备就绪

[英]Buffered Reader for a socket is never ready

Just to be completely transparent, this is for an assignment. 为了完全透明,这是一项任务。

There is more to do, but at the moment I'm just trying to get the following: 还有更多工作要做,但目前,我只是想获得以下信息:

  1. Node A reads in from a text file 节点A从文本文件读取
  2. Node A sends text file (minus the first line) to Node B using a socket 节点A使用套接字将文本文件(减去第一行)发送到节点B
  3. Node B read in from said socket, and prints it out to the console 节点B从所述套接字读取,并将其输出到控制台

However, right now, it seems that either the information isn't being sent, or it's not being read correctly by Node B. 但是,现在看来,节点B未正确发送信息或未正确读取信息。

In my main class, I set up the nodes like this: 在主类中,我像这样设置节点:

NodeA nodeA = new NodeA();
NodeB nodeB = new NodeB();

new Thread(nodeA).start();
new Thread(nodeB).start();

In node A, I do this: 在节点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();

Note that Node A's loop works fine. 请注意,节点A的循环工作正常。 It doesn't loop forever and does go through the intended lines of text when I tested with print statements. 当我使用print语句进行测试时,它不会永远循环,并且会遍历文本的预期行。

Then, on Node B's end: Updated to show current Node B code 然后,在节点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();;
}

However, in.ready() is never true. 但是,in.ready()永远都不是真的。 I've tried waiting around for that to happen using a while loop but it never occurs. 我尝试使用while循环等待发生这种情况,但从未发生。

I'm really not sure why. 我真的不确定为什么。 I have no idea if I set up the socket correctly, if I set up the server correctly, if I am listening correctly, etc. 我不知道我是否正确设置了套接字,是否正确设置了服务器,是否正确侦听等等。

I just figured that making B into a server which is listening for A made the most sense. 我只是觉得让B成为监听A的服务器是最有意义的。 I hope that's right. 我希望是正确的。 It looks similar to what I saw some other examples on SO did. 它看起来与我在SO上看到的其他示例相似。

Thank you for any and all help. 感谢您提供的所有帮助。 I'm extremely unfamiliar with sockets, ports, listening and otherwise, so forgive me if I don't understand your suggestions at first. 我对套接字,端口,监听和其他方式非常不熟悉,因此,如果我一开始不理解您的建议,请原谅我。 I'll do my best to understand it as I go. 我将尽我所能来理解它。

I refrained from adding the whole of the code to hopefully make it more readable and clear where the issue might be, but if you need more information just feel free to ask and I'll do my best to provide it. 我避免添加整个代码,以希望使代码更具可读性并弄清楚问题出在哪里,但是如果您需要更多信息,请随时提出问题,我会尽力提供。

The server must first get from the ServerSocket the Socket to the client. 服务器必须首先从ServerSocket将Socket获取到客户端。

connectionSocket = mySocket.accept();

The server thread will be sleep till a client causes it to accept the connectionSocket. 服务器线程将一直处于睡眠状态,直到客户端使它接受connectionSocket。

Then you can read from the connectionSocket. 然后,您可以从connectionSocket中读取。 ready not being needed. ready不需要。

As this is an assignment, I leave the rest to you. 由于这是一项任务,因此我将其余部分留给您。


By the way a typical server would do: 顺便说一句,典型的服务器可以做到:

for (;;) {
    Socket socket = serverSocket.accept();
    ... pass the socket to a thread from a pool of threads
}

I think the problem is that ready just means that if you call a read, it won't block. 我认为问题在于,就绪只是意味着如果您调用读取,它将不会阻塞。 You can see the code that gets executed if you look up the function on grepcode: 如果在grepcode上查找函数,则可以看到执行的代码:

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

A ready thread just means it's not going to block, which is useful when you want to ensure that your thread isn't going to get tied up, but doesn't really tell you if you have buffer or not. 一个就绪的线程只是意味着它不会被阻塞,这在您要确保线程不会被束缚,但是并不能真正告诉您是否有缓冲区时非常有用。

What you want to do is perform the readline, as a blocking call, until the data is consumed. 您要做的是执行readline(作为阻塞调用),直到消耗完数据为止。 If you don't want this blocking your current thread, then spin off a new consumer thread specific for this reading that can block. 如果您不希望这样阻塞您的当前线程,那么请分派一个专用于此可能阻塞的读取的新使用者线程。

Also, make sure that you're ending your send communication with either a closed socket or flush to indicate to the consuming stream when it is complete. 另外,请确保使用封闭的套接字或刷新来结束发送通信,以指示消费流何时完成。 And you only need to socket accept once per open/close session. 并且您只需要对每个打开/关闭会话进行一次套接字接受。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM