Java客户端与Python服务端Socket连接问题:接收消息时触发文件结束错误
Java Client to Python Server Communication: Fixing "OSError: got end of file during message"
我正在尝试实现Java客户端向Python服务端发送消息的功能,以下是我的代码:
Java客户端代码:
import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; public class Client { public static void main(String[] args) throws IOException { // need host and port, we want to connect to the ServerSocket at port 7777 Socket socket = new Socket("localhost", 7777); System.out.println("Connected!"); // get the output stream from the socket. OutputStream outputStream = socket.getOutputStream(); // create a data output stream from the output stream so we can send data through it DataOutputStream dataOutputStream = new DataOutputStream(outputStream); System.out.println("Sending string to the ServerSocket"); // write the message we want to send dataOutputStream.writeUTF("Hello from the other side!"); dataOutputStream.flush(); // send the message dataOutputStream.close(); // close the output stream when we're done. System.out.println("Closing socket and terminating program."); socket.close(); } }
Python服务端代码:
from multiprocessing.connection import Listener address = ('localhost',7777) while True: with Listener(address, authkey=None) as listener with listener.accept() as conn: print(conn.recv())
当我运行代码时,Python服务端抛出错误:
OSError: got end of file during message
请问我的代码哪里出问题了?
嘿,问题的核心在于两边用的通信协议完全不兼容!
- Java端用的是标准TCP Socket,通过
DataOutputStream.writeUTF()发送数据——这个方法会先写入两个字节的大端序长度前缀,再发送UTF-8编码的字符串内容,是Java标准的Socket通信格式。 - 而Python端用的
multiprocessing.connection.Listener是Python专门为**进程间通信(IPC)**设计的组件,它有自己的私有通信协议,和普通TCP Socket完全不匹配。所以当Python端试图按照自己的协议解析Java发来的字节流时,就会因为格式不对报错“got end of file during message”。
解决方案:改用Python标准socket模块接收
最直接的修复方式是把Python服务端改成用标准socket模块,来匹配Java的Socket通信格式。因为writeUTF()的格式是固定的,我们需要先读取两个字节的长度,再读取对应长度的内容:
修改后的Python服务端代码:
import socket HOST = 'localhost' PORT = 7777 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() print(f"Waiting for connection on {HOST}:{PORT}...") while True: conn, addr = s.accept() with conn: print(f"Connected by {addr}") # 先读取两个字节的长度前缀(Java writeUTF的格式) length_bytes = conn.recv(2) if not length_bytes: break # 转换为大端序整数 message_length = int.from_bytes(length_bytes, byteorder='big') # 读取对应长度的消息内容 message_bytes = conn.recv(message_length) # 解码为字符串 message = message_bytes.decode('utf-8') print(f"Received: {message}")
为什么这样能行?
- 我们用Python的标准
socket模块创建了普通TCP服务端,和Java的Socket完全兼容。 - 严格按照Java
writeUTF()的格式,先读取两个字节的长度标识,再读取对应长度的字节数据,最后解码成UTF-8字符串,完美匹配Java端的发送逻辑。
现在重新运行Java客户端和修改后的Python服务端,就能正常接收消息啦!
内容的提问来源于stack exchange,提问作者josh
相关产品推荐
相关产品推荐

