发送TCP后,为什么endian会反转

use*_*521 8 c# python sockets

我有一个用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)

Ste*_*ich 8

您的代码有问题:

长度是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套接字读取,因此读取加密数据而不是解密数据.

  • @ user740521:请不要让你的问题成为移动目标.找到了读取错误数据的初始问题.现在你刚刚改变了问题,给出了不同的 - 不一致的 - 你声称你的实际长度为8的13330654897016668160的值,即使你的实际长度为185,正如你在评论中正确显示但不是这个问题. (3认同)