TCP大端小端问题

小阳光

workerman 需要处理大端小端问题吗?网络字节序是大端,如果服务器是小端,应该需要转换,这个转换是谁完成的呢?如果是workerman完成的我想看看workerman转换的代码,我没有看到源码有这个操作。还是说需要开发人员自己收到数据后转换?

3099 2 0
2个回答

walkor

workerman不关心传输的数据是什么,业务传输的是大端,就是大端,传输的是小端就是小端。

  • 小阳光 2020-07-11

    前提 :网络序是大端,和机器操作系统无关,

    假设 1 服务器机器是小端序。

    假设 2 我们要开发一个workerman的http服务

    例:客户端发送 int 0x12345678,(大端 0x12, 0x34, 0x56, 0x78 小端 0x78, 0x56, 0x34, 0x12 ),因为网络序是大端固定的,也就是说不管什么客户端发送0x12345678都是0x12, 0x34, 0x56, 0x78 给workerman的tcp服务端

    在workerman服务器收到后如果没有处理就给了上层协议http,这是服务器是小端序,它解析0x12, 0x34, 0x56, 0x78 不就不是原来的 0x12345678了吗?

    如果workerman没有处理大小端,那么上层的http服务器必须要先转换大小端吧?不然客户端发送的int 0x12345678 服务器解析不出是int 0x12345678呀。

    综上我的意思是如果workerman的tcp 不管大小端 那么基于workerman tcp协议的http服务就必须转换才对。他们总有一个要处理才对。(我在现有的http服务里面没有找到转换代码,按照道理是底层转换才对,不可能http来转,我在想 是不是$buffer = fread($socket, self::READ_BUFFER_SIZE); 这里就转换好了,也就说 fread函数帮我们做了这件事?)

    有理解错误的地方请大神纠正。

  • blogdaren 2020-07-12

    @6917:
    你举的这个例子我也有同样的疑惑,fread应该是没干这个事情,其中的几个应用层协议比如frame、ws、websocket源码中有pack/unpack的身影,这个是用来是进行网络大端序处理的,但是这个http协议里却看不到,不明白是怎么处理这个大端小端序的; 我整体也理解不了,期待老大指点迷津。

walkor

首先,
workerman底层永远不会转换字节序,传输的是什么就是什么。

然后协议层,有些协议不涉及字节序,有些协议本身在包头可能有涉及字节序。包头涉及字节序的就按照协议规定字节序解析即可。

HTTP协议作为举例:
HTTP头
http协议是文本协议,协议本身不涉及大小端解析,抓包你能看到,http头是类似 GET / HTTP1.1\r\nHost: ...的明文字符。包头如果涉及数字的传输,都是用明文字符传输。所以http协议层没有大小端转换的说法。

HTTP包体
如果http协议传输的数据中包含了需要考虑字节序的数据,需要客户端与服务端事先沟通好使用大端还是小端(一般都是用网络字节序也就是大端,这样每个机器都能容易识别),然后双方按照约定在业务逻辑里以约定好的字节序读取这部分数据。workerman底层以及http协议层面不会给你自动转换(它也无法给你转换,在程序看来数据都是字节,不知道数据具体含义,更不知道从哪一位开始表示一个大端或者小端的数据)。

其它协议也一样,
frame协议规定前4个字节是网络字节序的包长数据,workerman收到frame协议的数据后,在协议层会以网络字节序解析并得到这个包长。去掉前4个字节剩下的是包体数据。与http协议一样,包体是否有包含字节序的数据以及具体是大端还是小端,位置在第几个字节,frame协议不关心也不会自动解析转换,因为他们都是业务逻辑该处理的事情。

  • blogdaren 2020-07-13

    @1 也就是说除了某些协议自身可能涉及到字节序外,其他涉及到字节序的数据都是需要交由客户端和服务端在业务层互相协调按照约定来处理,这样理解对吗?

  • walkor 2020-07-13

年代过于久远,无法发表回答
🔝