Java和Python之间的套接字连接-struct.unpack错误

Java和Python之间的套接字连接-struct.unpack错误,java,python,sockets,Java,Python,Sockets,我使用DataOutputStream通过套接字将int发送到Python,但是我在Python部分接收到的数据偶尔会损坏,并出现以下错误: 解包需要长度为4的字符串参数 更不用说我反复运行Java部分了。我不知道为什么会这样。请帮忙 以下是Java部分: public static void main(String[] args) { Socket sock = null; DataOutputStream out = null; try {

我使用
DataOutputStream
通过套接字将
int
发送到Python,但是我在Python部分接收到的数据偶尔会损坏,并出现以下错误:

解包需要长度为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
2
2.
2.
回溯(最近一次呼叫最后一次):
文件“test_socket1.py”,第20行,在
unpack=int(结构解包('>i',数据)[0])
struct.error:解包需要长度为4的字符串参数

来自Python文档:

socket.recv(bufsize[,flags])

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

传递到
recv
size
是最大大小。因此,在读取时,只要缓冲区中有数据,函数就会立即返回该字节数。因此,您可以将一个3字节的字符串解析为一个整数(需要4个字节)

我建议您检查接收的字节长度。如果小于4,请睡眠几毫秒,然后重试。最后,在解析之前将所有段连接成一个段

[编辑] 发现这篇文章谈论了类似的事情:


另外,我需要纠正我之前说过的话。您不需要几毫秒的睡眠时间(也称为显式调用
time.sleep(几毫秒)
,您可以立即再次调用
recv
,它将阻塞,直到出现新数据。如果新数据实际上在几微秒内到达,您就不会在睡眠中浪费几毫秒的时间。

您最好将数据序列化为适合网络通信的格式,如JSON/XML,同时避免字节顺序、endianness等,否则,您的方法将变得混乱!您是否可以为该解包行添加try-and-except-catch,并且当您捕获异常时,将数据打印出来?这样您就可以知道代码抛出异常时数据变量包含什么