不同的计算机系统在存储由多个字节组成的信息时,有些系统将高序字节存放在低地址处,而有些系统则将低序字节存放在低地址处,即“大序在前”(Big-Endian)和“小序在前”(Little-Endian)。在计算机网络中,发送端在传输数据之前必须要将用主机字节Host-byte顺序表示的数据转化成网络字节Network-byte顺序,然后才能发送数据。在数据接收端,系统要把收到的网络字节顺序的数据转化为主机字节顺序的数据。
在Winsock API中,专门有一类函数用来进行主机字节顺序和网络字节顺序数据的相互转化,这类函数称为字节排序函数:
1)4字节主机字节顺序的数转化为网络字节顺序---htonl()和WSAHtonl()
在Winsock1中提供的htonl()的格式是:
u_long WSAAPI htonl(
__in u_long hostlong //将要转换为网络字节顺序的32位数
);
在Winsock2中提供的WSAHtonl()函数的扩展格式是:
int WSAAPI WSAHtonl(
__in SOCKET s, //套接字标识
__in u_long hostlong, //将要转换为网络字节顺序的32位数
__out u_long *lpnetlong //一个指向32位的网络字节顺序数的指针
);
成功返回值为0,失败时返回SOCKET_ERROR错误信息,进一步调用WSAGetLastError()函数取得对该错误的具体描述,错误代码如下:
WSANOTINITIALISED //在调用本API之前应成功调用WSAStartup()
WSAENETDOWN //网络子系统失败
WSAENOTSOCK //描述字不是一个套接口
WSAEFAULT //指针参数lpnetlong不在有效的用户地址空间中
2)2字节主机字节顺序的数转化为网络字节顺序---htons()和WSAHtons()
在Winsock1中提供的htons()函数格式是:
u_short WSAAPI htons(
__in u_short hostshort //将要转换为网络字节顺序的16位数
);
在Winsock2中提供的WSAHtons()函数的扩展格式是:
int WSAAPI WSAHtons(
__in SOCKET s, //套接字标识
__in u_short hostshort, //将要转换为网络字节顺序的16位数
__out u_short *lpnetshort //一个指向16位网络字节顺序数的指针
);
返回值和错误代码同上!
3)4字节网络字节顺序的数转化为主机字节顺序---ntohl()和WSANtohl()
在Winsock1中提供的ntohl()函数的格式是:
u_long WSAAPI ntohl(
__in u_long netlong //一个以网络字节顺序表示的32位数
);
在Winsock2中提供的WSANtohl()函数的扩展格式是:
int WSAAPI WSANtohl(
__in SOCKET s, //套接字标识
__in u_long netlong, //一个以网络字节顺序表示的32位数
__out u_long *lphostlong //指向一个32位主机字节顺序数的指针
);
返回值和错误代码同上!
4)2字节网络字节顺序的数转化为主机字节顺序---ntohs()和WSANtohs()
在Winsock1中提供的ntohs()函数的格式是:
u_short WSAAPI ntohs(
__in u_short netshort //一个以网络自己诶顺序表示的16位数
);
在Winsock2提供的WSANtohs()函数的扩展格式是:
int WSAAPI WSANtohs(
__in SOCKET s, //套接字标识
__in u_short netshort, //一个以网络自己诶顺序表示的16位数
__out u_short *lphostshort //指向一个16位主机字节顺序数的指针
);
返回值和错误代码同上!