简体   繁体   English

套接字多线程 - 读取输入流暂停线程

[英]Socket Multithreading - Reading input stream pauses thread

I'm testing out sockets on my local machine. 我正在测试本地机器上的套接字。 I'm trying to run both a socket and server in one program using threads. 我正在尝试使用线程在一个程序中运行套接字和服务器。 My server is an echo server so that it sends back whatever message it receives. 我的服务器是一个echo服务器,因此它会发回它收到的任何消息。 My problem is that when I start both threads, on both the client and server, they 'freeze' when they reach the part where I read from the input stream. 我的问题是,当我在客户端和服务器上启动两个线程时,当它们到达我从输入流中读取的部分时,它们会“冻结”。 It works fine up to the part where the client sends the message. 它适用于客户端发送消息的部分。 Afterwards, it simply stops as it appears that the client is waiting for a message and so is the server even if I already sent a message to the server via writing to the outputstream. 之后,它只是停止,因为看起来客户端正在等待消息,即使我已经通过写入输出流向服务器发送消息,服务器也是如此。 What's wrong with the code? 代码有什么问题?

Client.java Client.java

@Override
    public void run() {

        try {
            Socket socket = new Socket("localhost", 22600);

            BufferedReader br = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                    socket.getOutputStream()));
            BufferedReader input = new BufferedReader(new InputStreamReader(
                    System.in));
            System.out.println("Client 1");

            while (true) {

                System.out.print("\nEnter text : ");
                String inputText = input.readLine();
                writer.write(inputText);
                System.out.println("Client 2");

                System.out.println("Client 3");
                String s = br.readLine();
                System.out.println("CLIENT RECEIVED : " + s);

            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

Server.java Server.java

@Override
public void run() {

    try {
        ServerSocket server = new ServerSocket(22600);
        Socket socket = server.accept();
        BufferedReader br = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                socket.getOutputStream()));


        System.out.println("Server 1");
        while (true) {

            System.out.println("Server 2");
            String s = br.readLine();
            System.out.println("Server 3");
            if (s == null) {
                System.out.println("NULL SERVER SIDE ERROR");
                break;
            }

            writer.write("ECHO : " + s);
            System.out.println("SYSOUT ECHO " + s);

        }
        server.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

You are writing a string that does not have an end-of-line at its end. 您正在编写一个字符串,其末尾没有行尾。

            String inputText = input.readLine();
            writer.write(inputText);
            System.out.println("Client 2");

The inputText string does not include the end-of-line you typed. inputText字符串不包括您键入的行尾。 And you write it as-is to the server. 然后你按原样把它写到服务器上。 However, the server tries to read a line: 但是,服务器尝试读取一行:

        String s = br.readLine();
        System.out.println("Server 3");

So it will keep waiting until the client sends in a newline. 所以它会一直等到客户端发送换行符。 But by now the client is waiting for an answer from the server, and now they are deadlocked. 但到目前为止,客户端正在等待服务器的回答,现在它们已陷入僵局。

So, you should add a writer.newLine() to the client, as well as the server's echo, which suffers from the same issue. 因此,您应该将writer.newLine()添加到客户端,以及服务器的echo,它会遇到同样的问题。 It's also recommended, after each write, to use writer.flush() , on both server and client. 在每次写入之后,还建议在服务器和客户端上使用writer.flush() Otherwise, it may wait until the buffer is full before actually writing, and the same deadlock will result. 否则,它可能会等到缓冲区已满,然后才会实际写入,并导致相同的死锁。

The readLine method of BufferedReader requires a new line terminator to return a value (unless the end of Stream is reached), and then returns the line without this character. BufferedReaderreadLine方法需要一个新的行终止符来返回一个值(除非到达Stream的末尾),然后返回没有该字符的行。 So the Client 所以客户

  1. Reads a line from the user into the variable inputText 从用户读取一行到变量inputText
  2. Client writes inputText to the OutputStream 客户端将inputText写入OutputStream
  3. Server receives data, but waits until it receives a new line (which it does not). 服务器接收数据,但等待它收到一个新行(它没有)。

If you wish to use new line as a delimiter for communication, append this to the end of the data sent 如果您希望使用新行作为通信分隔符,请将其附加到发送数据的末尾

writer.write(inputText + "\n");

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

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