如何从Java发送一个4字节的头并用Python读取它?

如何从Java发送一个4字节的头并用Python读取它?,java,python,tcp,bytearray,Java,Python,Tcp,Bytearray,我试图通过TCP套接字从Java应用程序发送消息,并在Python 2.7中读取它 我希望前4个字节指定消息长度,以便执行以下操作: header = socket.recv(4) message_length = struct.unpack(">L",header) message = socket.recv(message_length) 在Python端 Java方面: out = new PrintWriter(new BufferedWriter(new StreamWrite

我试图通过TCP套接字从Java应用程序发送消息,并在Python 2.7中读取它 我希望前4个字节指定消息长度,以便执行以下操作:

header = socket.recv(4)
message_length = struct.unpack(">L",header)
message = socket.recv(message_length)
在Python端

Java方面:

out = new PrintWriter(new BufferedWriter(new StreamWriter(socket.getOutputStream())),true);
byte[] bytes = ByteBuffer.allocate(4).putInt(message_length).array();
String header = new String(bytes, Charset.forName("UTF-8"));
String message_w_header = header.concat(message);
out.print(message_w_header);
这对某些消息长度(10102个字符)有效,但对其他消息长度(例如1017个字符)无效。如果输出得到的每个字节的值,则值失败:

Java:
Bytes 0 0 3 -7
Length 1017
Hex string 3f9

Python:
Bytes 0 0 3 -17
Length 1007
Hex string \x00\x00\x03\xef

我认为这与Java中的有符号字节和Python中的无符号字节有关,但我不知道该怎么做才能使其正常工作。

问题出在Java端--
b'\x03\xf9'
不是有效的utf-8字节序列:

>>> b'\x03\xf9'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf9 in position 1: invalid start byte
这就是为什么在Python中接收的是
b'\x03\xef'
,而不是
b'\x03\xf9'

要修复此问题,请使用Java而不是Unicode文本发送字节


不相关,
sock.recv(n)
返回的字节数可能小于
n
。如果插座堵塞;您可以使用
file=sock.makefile('rb')
创建一个类似文件的对象,并调用
file.read(n)
来准确读取
n
字节。

在Java代码中,输出的
类型是什么,已编辑的代码。您确定python正在使用UTF-8吗?更改默认编码没有任何区别。您不能将任意二进制(原始32位整数)解码为UTF-8。不要将消息长度放入
字符串
,而是将消息和标题放入
字节[]
。感谢您的详细解释。考虑到字符流后来在Java中引入,我认为应该有一种“神奇”的方法来处理字符流,这似乎误导了我自己。
>>> b'\x03\xf9'.decode('utf-8', 'replace').encode('utf-8')
b'\x03\xef\xbf\xbd'