TCP 服务器 (Java) 未从 TCP 客户端 (Python) 接收数据包

TCP Server (Java) not receiving Packets from TCP Client (Python)

问题

我有一个侦听端口 55555 的 TCP 服务器 (Java)。一旦客户端连接到它,它就会侦听一个数据包,如果数据包正确,则打开一个新套接字并发送客户端的新端口。我知道服务器端代码可以工作,因为我写了一个小的 java 客户端可以正常工作,但是我的 python 客户端只能连接(当它发送数据包时服务器不会似乎对此有反应)。

我希望有人知道如何让它工作,在此先感谢您的帮助!

我还尝试了什么

  1. 将“\n”“\r\n”附加到 python 数据包:结果相同
  2. 搜索 Whosebug,一个多小时没找到任何东西

代码

服务器

// Server.java
private void run() {
    while (true) {
        try {
            ssocket = new ServerSocket(config.defaultPort);
            System.out.println("Socket opened on port "+config.defaultPort);
            Socket socket = ssocket.accept();
            System.out.println("Connection established");
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            String msg = dis.readUTF();
            System.out.println("Packet received");
            ssocket.close();
            if (msg.startsWith(config.specialChars.get("initConnectionServer").toString())) {
                System.out.println("Connection initiated by another server");
                // Connection was initiated by another server
                // parse message
                String[] parts = msg.substring(1).split(config.specialChars.get("listSeparator").toString());
                String name = parts[0];
                String passwd = parts[1];
                /// check name and password
                if (BCrypt.checkpw(passwd, config.ServerPW) && name.equals(config.ServerName)) {
                    System.out.println("Password and Name match our Server Network");
                    // add new server worker
                    ServerWorkerServer t = new ServerWorkerServer();
                    t.start();
                    workers.add(t);
                    // send new port
                    DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                    dos.writeUTF(""+config.specialChars.get("newPortResponse")+t.port);
                    dos.flush();
                    System.out.println("new port sent back: "+t.port);
                    socket.close();
                    ssocket.close();
                } else {
                    if (name.equals(config.ServerName)) {
                        System.out.println("Password does not match our server network");
                        System.out.println(passwd);
                    } else {
                        System.out.println("Name does not match our server network");
                        System.out.println(name);
                    }
                }
            } else {
                System.out.println("Message is not valid");
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

测试客户端 java:

// client.java
public static void main(String[] args) {
    try{
        Socket s = new Socket("localhost",55555);
        DataOutputStream dout = new DataOutputStream(s.getOutputStream());
        dout.writeUTF("\uE001OG-ServerNet\uE000password");
        dout.flush();
        dout.close();
        s.close();
    }catch(Exception e){System.out.println(e);}
}

测试客户端 python:

# client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 55555))
s.send(b"\uE001OG-ServerNet\uE000password")

输出

所有输出均来自 server.java 相应客户端连接后

client.java

Socket opened on port 55555
Connection established
Packet received
Connection initiated by another server
Password and Name match our Server Network
new port sent back: 29517

client.py

Socket opened on port 55555
Connection established

注释

config.specialChars.get("initConnectionServer") returns \uE001

config.specialChars.get("listSeparator") returns \uE000

config.specialChars.get("newPortResponse") returns \uE002

这两个语句传输的数据不同:

 Java:   out.writeUTF("\uE001OG-ServerNet\uE000password");
 Python: s.send(b"\uE001OG-ServerNet\uE000password")

Java 语句将给定的字符串解释为 Unicode。它会将字符串转换为 UTF-8,从而传输字节序列:

 \xee\x80\x81OG-ServerNet\xee\x80\x80password

Python 语句将给定的字符串解释为字节序列,因为它是使用 b"..." 语法明确声明的。这意味着它将传输以下字节序列:

 \uE001OG-ServerNet\uE000password

要传输与 Java 代码相同的内容,请不要使用 b"...",而应使用 "...".encode()。这会将字符串解释为 Unicode 并将其转换为 UTF-8 字节序列。