Java与Python之间的Socket连接 - struct.unpack错误

0 投票
1 回答
1302 浏览
提问于 2025-04-18 18:00

我在用 DataOutputStream 通过套接字(socket)把 int 发送到 Python,但有时候在 Python 这边收到的数据会出问题,出现了以下错误:

unpack requires a string argument of length 4

更糟的是,我的 Java 部分是反复运行的。我完全不知道为什么会这样。请帮帮我。

这是 Java 的部分代码:

public static void main(String[] args) {

        Socket sock = null;
        DataOutputStream out = null;

        try {
            sock = new Socket("192.168.0.104", 1234);
            out = new DataOutputStream(sock.getOutputStream());

            out.writeInt(2);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                sock.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
}

这是 Python 的部分代码:

import socket
import struct

host = '192.168.0.104'
port = 1234
backlog = 5
size = 4
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(backlog)
while 1:
    client, address = s.accept()
    data = client.recv(size)
    unpacked = int(struct.unpack('>i', data)[0])
    if data:
        print unpacked
    client.close() 

这是输出结果:

2
2
2
Traceback (most recent call last):
  File "test_socket1.py", line 20, in <module>
    unpacked = int(struct.unpack('>i', data)[0])
struct.error: unpack requires a string argument of length 4

1 个回答

2

来自Python文档的内容:

socket.recv(bufsize[, flags])

从套接字接收数据。返回值是一个字符串,表示接收到的数据。一次最多可以接收的数据量由bufsize指定。有关可选参数flags的含义,请参见Unix手册页recv(2);默认值为零。

你传给recvsize是最大值。所以在读取的时候,只要缓冲区里有数据,这个函数就会立即返回那个字节数。因此,你可能会把一个3字节的字符串解析成一个整数(而整数需要4个字节)。

我建议你检查接收到的字节长度。如果少于4字节,等几毫秒再试一次。最后,在解析之前,把所有的片段拼接成一个。

[编辑]

发现了一个类似的帖子:Python socket recv from java client

另外,我需要纠正我之前说的。你不需要等几毫秒(也就是,明确调用time.sleep(a_few_milliseconds)),你可以立即再次调用recv,它会阻塞,直到有新数据到来。如果新数据在几微秒内到达,你就不会浪费几毫秒去等待。

撰写回答