网路字节序和主机字节序

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.

结论:数据成功接受。所以传输数据的时候最好进行一下主机和网络字节序的转换。


你可能感兴趣的:(数据分析,网络,服务器)