首页 > 解决方案 > 使用 Python 客户端写入 Java 服务器

问题描述

我正在尝试使用套接字连接将 Python 和 Java 结合起来。我有一个 Java 服务器和一个 Python 客户端。它们能够相互连接,并且服务器能够写入客户端,但是当我尝试从客户端向服务器发送消息时,它会抛出 EOFException。我应该怎么做才能让它工作?

服务器代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    
    public static void main(String[] args) {
        try {
            ServerSocket serversocket = new ServerSocket(6000);
            Socket client = serversocket.accept();

            final DataInputStream input = new DataInputStream(client.getInputStream());
            final DataOutputStream output = new DataOutputStream(client.getOutputStream());

            output.writeUTF("Hello Client!");

            String message = (String)input.readUTF();
            System.out.println(message);

            serversocket.close();

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

客户端代码:

import socket

socket = socket.socket()
host = "localhost"
port = 6000
socket.connect((host, port))

message = socket.recv(1024)
print(message.decode())

socket.sendall("Hello Server".encode())

socket.close()

例外:

java.io.EOFException
        at java.base/java.io.DataInputStream.readFully(DataInputStream.java:203)
        at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:615)
        at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:570)
        at Server.main(Server.java:19)

标签: javapythonsockets

解决方案


选项1:

input.readUTF()在服务器中替换为:

   while(true) {
         int ch = input.read();
         if (ch == -1) break;
         System.out.print((char)ch);
   }

选项#2:

如果想在服务器上读取 UTF 编码的字符串(与纯 ASCII 相比),那么建议使用带有 utf-8 字符集和 readLine() 的 BufferedReader。

ServerSocket serversocket = new ServerSocket(6000);
System.out.println("Waiting for connections");
Socket client = serversocket.accept();

final BufferedReader input = new BufferedReader(
    new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8)); // changed
final OutputStream output = client.getOutputStream();

//output.writeUTF("Hello Client!"); // see note below
output.write("Hello Client!".getBytes(StandardCharsets.UTF_8)) // changed

String message = input.readLine(); // changed
System.out.println(message);

client.close();
serversocket.close();

客户端输出:

Hello Client!

服务器输出:

Hello Server

注意DataOutputStream#writeUTF(...)的 JavaDoc说:

首先,两个字节被写入输出流,就好像通过 writeShort 方法给出了后面的字节数。

使用output.write(s.getBytes(StandardCharsets.UTF_8))与非 Java 客户端更兼容。Python utf-8 解码不支持 writeUTF() 添加的 2 字节长度前缀。

最后,如果希望服务器处理多个客户端连接,则在创建 ServerSocket 后添加一个包含代码的循环,并且只关闭循环内的客户端套接字。


推荐阅读