1.网络传数据的时候是一个字节一个字节的传.字符串里的每一个字符只用一个字节,前面的就先传, 接收的后再解释的时候也是按顺序来, 所以字符串没有网络字节序的分别.
2.网络字节序默认是大端,也就是说任何机器如果收到一个int型的4个字节,那么这个机器就会认为第一个字节是最高位,最后一个字节是最低位。
我们看看下面这个实例:
比如我们要传个int数据,假设数据为
/*假设网络连接已经建立好,网络描述符为fd*/
服务器:
...
int send = 1;
Write(fd, &send, sizeof(send));
我们看一下数据的传递过程,假设这一端主机是小端字节序,那么这个过程应该是:
01 | 00 | 00 | 00 |
注:从左到右地址增大,这个是在用户空间的摆放形式
Write后,数据被拷贝到内核驱动空间,形式还是一样的。
01 | 00 | 00 | 00 |
注:从左到右地址增大
然后就是网卡驱动把这个字节发出去了,形式还是一样。但是它是这样来表现的,01字节先发,最后是00那个字节,这样我们的服务器端的数据就分析完毕了。
客户端:(大端主机字节序)
...
Int get = 0;
Read(fd, &get, sizeof(get));
一开始:
00 | 00 | 00 | 00 |
注:从左到右地址增大,这个是在用户空间的摆放形式
Read的过程:
网卡驱动收到数据
01 | 00 | 00 | 00 |
,他知道是网络传过来的数据都是大端数据,所以他就解释为接受到了数据:0x01000000
因为主机序也是大端,所以不转换,直接把内核空间的数据拷贝到用户空间,就为:get=0x01000000.
结论:数据传输失败。
那么错误原因在哪里呢?理由就是发送数据端应该先转换为网络字节序;如果服务器端这样写:
服务器:
...
int send = htonl(1);
Write(fd, &send, sizeof(send));
我们看一下数据的传递过程,假设这一端主机是小端字节序,那么这个过程send的内容应该是:
00 | 00 | 00 | 01 |
注:从左到右地址增大,这个是在用户空间的摆放形式
Write后,数据被拷贝到内核驱动空间,形式还是一样的。
注:从左到右地址增大
然后就是网卡驱动把这个字节发出去了,形式还是一样。但是它是这样来表现的,00字节先发,最后是01那个字节,这样我们的服务器端的数据就分析完毕了。
那么在客户端收到的数据分析就为:
客户端:(大端主机字节序)
...
Int get = 0;
Read(fd, &get, sizeof(get));
一开始:
00 | 00 | 00 | 01 |
注:从左到右地址增大,这个是在用户空间的摆放形式
Read的过程:
网卡驱动收到数据
00 | 00 | 00 | 00 |
,他知道是网络传过来的数据都是大端数据,所以他就解释为接受到了数据:0x00000001(其实在这里就决定了你的数据接受的是否正确,这里成功解释了,后面系统才可以正确的进行字节序转换)
因为主机序也是大端,所以不转换,直接把内核空间的数据拷贝到用户空间,就为:get=0x00000001.
结论:数据成功接受。所以传输数据的时候最好进行一下主机和网络字节序的转换。