我有一个用C#编写的客户端和一个用python编写的服务器.我通过套接字发送的消息是8个字节,后跟数据,8个字节是数据长度.
在发送之前的C#中,我将8字节数据长度转换为太大的endian,如图所示:
public void Send(SSLMsg m)
{
string json = m.Serialize();
byte[] data = Encoding.ASCII.GetBytes(json);
ulong dataLen = (ulong)data.Length;
byte[] dataLenPacked = packIt(dataLen);
Log("Sending " + dataLen + " " + json);
sslStream.Write(dataLenPacked);
sslStream.Write(data);
sslStream.Flush();
}
private byte[] packIt(ulong n)
{
byte[] bArr = BitConverter.GetBytes(n);
if (BitConverter.IsLittleEndian)
Array.Reverse(bArr, 0, 8);
return bArr;
}
Run Code Online (Sandbox Code Playgroud)
消息发送成功,我在python服务器代码中被绑定,因为unpack格式应该是正确的,不应该吗?
(length,) = unpack('>Q', data)
# len(data) is 8 here
# length is 1658170187863248538
Run Code Online (Sandbox Code Playgroud)
不是big-endian字符'>'?为什么我的长度太长了?
有一个错误,我正在解包错误的8个字节,已经修复,现在我正在解包正确的数据,我仍然有相同的问题.
(length,) = unpack('>Q', data)
# len(data) is 8 here
# length is 13330654897016668160L
Run Code Online (Sandbox Code Playgroud)
只有当我使用小端解包时,才会给出正确的长度,即使我使用big-endian将字节发送到服务器...所以我希望> Q能够工作,而是
(length,) = unpack('<Q', data)
# len(data) is 8 here
# length is 185
Run Code Online (Sandbox Code Playgroud)
这是我在python中接收字节的方式:
while (True):
r,w,e = select.select(...)
for c in r:
if (c == socket):
connection_accept(c)
else
# c is SSL wrapped at this point
read = 0
data = []
while (read != 8):
bytes = c.recv(min(8-read, 8))
read += len(bytes)
data.append(bytes)
joinedData = ''.join(data)
# the below length is 13330654897016668160L
# I am expecting it to be 185
(length,) = unpack('>Q', joinedData)
# the below length is 185, it should not be however
# since the bytes were sent in big-endian
(length,) = unpack('<Q', joinedData)
Run Code Online (Sandbox Code Playgroud)
您的代码有问题:
长度是1658170187863248538
这是十六进制1703010020BB4E9A.这与8的长度无关,无论涉及哪个字节.相反,它看起来像TLS记录:
17 - record type application data (decimal 23)
03 01 - protocol version TLS 1.0 (aka SSL 3.1)
00 20 - length of the following encrypted data (32 byte)
..
Run Code Online (Sandbox Code Playgroud)
因为根据你的代码你正在做SSL,你的接收器可能有问题.我的猜测是你从普通套接字而不是SSL套接字读取,因此读取加密数据而不是解密数据.