再议字节序-------TCP/IP网络传输相关字节序

对于网络这一块的字节序,说实话,理解不够深,在网上学些了下,先整理点,以后继续完善。

一、
在网络编程时,并不是什么时候都要考虑字节序问题。那么什么时候需要考虑呢?
实际上如果是应用层的数据,即对TCP/IP来说是透明的数据,不用考虑字节序的问题。 因为发出去是什么样子,接收到就还是什么样子,接收端收到的顺序是和发送端一致的
TCP/IP协议本身处理数据的时候都是按照网络字节序来处理的。当一个数据是应用层和TCP/IP都需要关心的时候,如网络函数的数字类型参数,需要考虑这个数据的字节序(一般而言就是IP地址和端口号)。

例如我指定了一个端口号:
unsigned short port = 0x0012  (十进制18)
把这个端口号传个TCP/IP建立一个socket连接。
sockaddr_in addr;
 addr.sin_family = AF_INET; //使用互联网际协议,即IP协议
 addr.sin_port = port;
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
因为网络字节序是big endian,即低地址存放的是数值的高位,所以TCP/IP实际上把这个port解释为0x1200(十进制4608)。本来打算是要在端口18建立连接的,但TCP/IP协议栈却在端口4608建立了连接。故先用htons(port)把端口号转换成网络字节序,这样就可避免这种问题了。

二、
字节序问题归根结底就是因为它们的 编码单元是多个字节,而且这多个字节的顺序在不同机器上可能不一样(大头或小头字节序)。
如四个字节才能表示一个int整形,utf-16编码最小编码单元是两个字节。

对于TCP/IP而言,发送端的字节以什么顺序排列的,接受端就是受到完全一样顺序排列的字节。
接收方接收到数据后, 但是需要知道字节序才能正确地解析这些数据。

假设现在要在使用不同字节顺序的机器之间传输和交换数据,那该怎么办呢?
有两种方法,一种是全部转换成文本来传输,当然也要以两个主机有相同的字符集为基础;另一种是双方都按照某一方的字节顺序来传输(这时就有一个不同字节顺序之间的相互转换问题)。见Unix网络编程第一卷P118数据格式。

Socket编程中经常采用第二种方法。整个传输过程如下:发送端将本机的数据转换成网络的字节顺序(调用API函数htonl或htons),然后发送;接收端收到网络数据后,先将数据转换成本机的字节顺序(调用API函数ntohl或ntohs)。




你可能感兴趣的:(再议字节序-------TCP/IP网络传输相关字节序)