客户端和使用服务器套接字之间的通信客户端、通信、服务器

2023-09-08 09:08:13 作者:虚世の守护

好吧,这是从今天早些时候修订的问题,我已包括code有助于解释这个问题。我是从客户端发送两个消息发送到服务器。然后,服务器选取消息并处理它们。最后,服务器将尝试将消息发送回客户端(请注意在服务器code的TestMessage),这是我在这里遇到的问题。要么我不recieving消息在客户端或服务器端错误地发送。

Okay this is a revised question from earlier today, I have included code to help explain the problem. I am sending two messages from the client to the server. The server then picks the messages up and processes them. The server finally attempts to send a message back to the client(please note in the server code "testmessage"), it is here I am having problems. Either I am not recieving the message at the client side or sending it incorrectly from the server side.

public class ClientConnection {

String address, language, message;
int portNumber;
Socket clientSocket = null;

public ClientConnection(String lan, String mes, String add, int pn) throws IOException{
    address = add;
    portNumber = pn;
    language = lan;
    message = mes;
}
public String createAndSend() throws IOException{
    // Create and connect the socket
    Socket clientSocket = null;
    clientSocket = new Socket(address, portNumber);
    PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
    BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));     

    // Send first message - Message is being correctly received
    pw.write(language+"\n"); 
    pw.flush(); 
    // Send off the data  

    // Send the second message - Message is being correctly received
    pw.write(message); 
    pw.flush();
    pw.close();
    // Send off the data

    // NOTE: Either I am not receiving the message correctly or I am not sending it from the server properly.
    String translatedMessage = br.readLine();       
    br.close();
    //Log.d("application_name",translatedMessage); Trying to check the contents begin returned from the server.
    return translatedMessage;
}

服务器code:

Server Code:

public class ServerConnection {

public static void main(String[] args) throws Exception {       
    // Delete - Using while loop to keep connection open permanently.
    boolean status = false;
    while( !status){
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(1);
        }
        Socket clientSocket = null;
        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.err.println("Accept failed.");
            System.exit(1);
        }
        // Delete - Working as of here, connection is established and program runs awaiting connection on 4444
        BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));     
        String language = br.readLine();
        String message = br.readLine();
        // Test - Works
        System.out.println(language);      
        // Test - Works
        System.out.println(message);
        // Delete - Working as of here, both messages are passed and applied. Messages are received as sent from client.
        TranslateMessage tm = new TranslateMessage();
        String translatedMessage = tm.translateMessage(language, message);

        // NOTE: This seems to be where I am going wrong, either I am not sending the message correctly or I am not receiving it correctly..
        // PrintWriter writer = new PrintWriter(new BufferedOutputStream(clientSocket.getOutputStream()));
        PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
        // Send translation back 
        System.out.println(translatedMessage);
        // pw.write(translatedMessage+"\n"); 
        pw.write("Return test"); // Test message!
        pw.flush(); 
        // Send off the data 
        pw.close();
        br.close();
        clientSocket.close();
        serverSocket.close();
    }
}
}

在code是一个有点乱,我可以看到一些重复,我已经作了评论,我觉得问题occour。

The code is a bit of a mess and I can see a few duplicates, I have commented where I feel the problems occour.

感谢您的帮助!

推荐答案

您正在使用BufferedReader.readLine()读取来自服务器的响应,但在测试情况下,你要发送不与结束的字符串\\ n或\\ r \\ n,所以它不会从文档得到行,据我可以告诉...

You are using BufferedReader.readLine() to read the response from the server, but in the test case you are sending a string that is not terminated with a \n or \r\n, so it will not get the line as far as I can tell from the docs...

public String readLine()
            throws IOException

Read a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.

Returns:
    A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

另外一个建议...

An additional suggestion...

在写请求响应协议,这样我就不会靠行结束终止请求或响应。通常,我会使用一个完全格式化的JSON字符串,还是我的preference是一个二进制协议,其中所有的请求和响应都使用二进制计数(通常为4个字节大尾端/网络字节顺序)ppended $ P $。然后在客户端和服务器读取的4个字节然后读取后面的字节数。这种处理数据包碎片,通常情况通过网络连接,还有助于避免受到恶意用户的DOS攻击发送长字符串,永远不会终止。

When writing request response protocols like this I would not rely on line endings to terminate the requests or responses. Typically I would use either a fully formatted JSON string, or my preference is for a binary protocol where all requests and response are prepended with a binary count (usually 4 bytes bigendian/network byte order). Then the client and server reads the 4 bytes then reads the number of bytes that follow. This handles the packet fragmentation that typically happens over network connections, also it helps avoid DOS attacks by malicious users sending long strings that never terminate.

在Java中,你可以使用ByteBuffer.order()来处理大尾端号码。

In Java you can use ByteBuffer.order() to handle bigendian numbers.