java 套接字问题 - readline 无法正常工作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4457975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:29:11  来源:igfitidea点击:

Socket problem - readline won't work properly

javasockets

提问by Willy

I try to code a client and server connection using socket. The problem is my client can't read the response from the server (it hangs on the readline).

我尝试使用套接字对客户端和服务器连接进行编码。问题是我的客户端无法读取来自服务器的响应(它挂在 readline 上)。

Here is some of the code.

这是一些代码。

Server:

服务器:

    try {
        // Create the server socket.
        portNumber = Integer.parseInt(myParam.get("socket.portNumber"));
        System.out.println(portNumber);
        mainSocket = new ServerSocket(portNumber);

    } catch (IOException ioe) {
        System.out.println("Error Message : "+ioe.getMessage());
    }

    while(true)
    {     
        try
        {
            // Accept connections
            Socket clientSocket = mainSocket.accept();
            SocketServerThread st = new SocketServerThread (clientSocket);
            st.start();
        }
        catch(IOException ioe)
        {
            System.out.println("Error message :"+ioe.getMessage());
        }
    }

The Thread:

主题:

public void run() {

    BufferedReader in = null;
    PrintWriter out = null;
    String clientResponse = null;

    try {
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

        //Read The Message
        String clientRequest = in.readLine();
        System.out.println("Message recieved : " + clientRequest);

        //Process the message

        // Send response
        out.println(clientResponse+"\n");
        out.flush();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // Clean up
        try {
            in.close();
            out.close();
            clientSocket.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

The client:

客户端:

    try {
        // Create the server socket.
        simSocket = new Socket("192.168.52.27", portNumber);
    } catch (IOException ioe) {
        System.out.println("Error Message : " + ioe.getMessage());
    }
    BufferedReader in = null;
    PrintWriter out = null;
    try {
        in = new BufferedReader(new InputStreamReader(simSocket.getInputStream()));
        out = new PrintWriter(new OutputStreamWriter(simSocket.getOutputStream()));

            out.write("My message");
            out.flush();

            do{
            response = in.readLine(); //This is where the code hang
            }while (response.length()<= 0);

            System.out.print(response);

    } catch (IOException ioe) {
        System.out.println("Error message :" + ioe.getMessage());
    } finally {
        try {
            in.close();
            out.close();
            simSocket.close();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

Could you guys tell me what's the problem? Thank you very much for any help

你们能告诉我有什么问题吗?非常感谢您的帮助

回答by Sergei Tachenov

Okay, I've figured this one out. It's not the client that hangs, it's the server. It tries to read a line of text from the client, but the client doesn't send the line separator:

好的,我已经想通了这一点。挂起的不是客户端,而是服务器。它尝试从客户端读取一行文本,但客户端不发送行分隔符:

    out.write("My message");
    out.flush();

Replace write() with println() here.

在这里用 println() 替换 write()。

回答by Willy

OK, I made several editing in the code and now it run nicely :

好的,我在代码中进行了几次编辑,现在运行良好:

The server :

服务器 :

    try {
        // Create the server socket.
        portNumber = Integer.parseInt(myParam.get("socket.portNumber"));
        mainSocket = new ServerSocket(portNumber);

    } catch (IOException ioe) {
        System.out.println("Error Message : " + ioe.getMessage());
    }

    // Accept connections    
    try {
        clientSocket = mainSocket.accept();
    } catch (IOException ioe) {
        System.out.println("Error Message : " + ioe.getMessage());
    }
    BufferedReader in = null;
    PrintWriter out = null;

    while (true) {
        try {
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            //Read The Message
            **StringBuffer buffer = new StringBuffer();
            while (true) {
                int ch = in.read();
                if ((ch < 0) || (ch == '\n')) {
                    break;
                }
                buffer.append((char) ch);
            }
            String clientRequest = buffer.toString();**

            SocketServerThread st = new SocketServerThread(clientRequest, out);
            st.start();
        } catch (IOException ioe) {
            System.out.println("Can't accept connection. Error message :" + ioe.getMessage());
        }
    }

I change the readline with read and it work, so the assumption that "\n" is the problem is correct.

我用 read 更改了 readline 并且它起作用了,因此“\ n”是问题的假设是正确的。

The thread : a minor change in the thread (remove the reading request part since I already done that in the server)

线程:线程中的一个小改动(删除读取请求部分,因为我已经在服务器中完成了)

The Client: change the readline into read just like the server one.

客户端:将 readline 更改为 read 就像服务器一样。

Thank you all for the help

谢谢大家的帮助

回答by user207421

out.write("My message");

That doesn't send a line terminator so it can never be read. Use println().

这不会发送行终止符,因此永远无法读取。使用 println()。

out.println(clientResponse+"\n");

That will send the clientResponse plus a newline plus a \n. The last part will probably be interpreted as a blank line. Not much point in that. Remove the \n.

这将发送 clientResponse 加上一个换行符和一个 \n。最后一部分可能会被解释为一个空行。没有多大意义。删除\n。

do{
    response = in.readLine(); //This is where the code hang
}while (response.length()<= 0);

That's not the correct way to read lines. It will get an NPE at EOS; the response length can never be negative; and why would you send yourself blank lines? The correct way is this:

这不是阅读行的正确方法。它将在 EOS 上获得 NPE;响应长度不能为负数;为什么你会给自己发送空行?正确的方法是这样的:

while ((response = in.readLine()) != null) {
    // if (response.length() == 0) continue; // if you must
    // process the line
}
// when you get here EOS has occurred.

回答by Raghuram

Could it be because clientResponse(sent by server thread) is nulland the client is waiting for response size > 0?

可能是因为clientResponse(由服务器线程发送)是null并且客户端正在等待响应大小 > 0?

回答by Andreas Dolk

According to the javaDoc, the server response actually is

根据javaDoc,服务器响应实际上是

"My Message:\n"+System.getProperty("line.separator")

I bet, in.readLine()works fine at least once - but you just ignore the response, because the print command is outside the loop. Move that one up, and you should see the responses on the console.

我敢打赌,in.readLine()至少工作一次 - 但你只是忽略响应,因为打印命令在循环之外。将其向上移动,您应该会在控制台上看到响应。

There is a (very small) chance, that the servers println()doesn't really send a \nchar. So you could try this at the thread code:

有一个(非常小的)机会,服务器println()并没有真正发送一个\n字符。所以你可以在线程代码中尝试这个:

 out.print(clientResponse+"\n\n");  // exchanged println with an extra \n char