WIN32汇编语言教程:第16章 TCP/IP和网络通信 · 16.2 WinSock接口(4)
invoke inet_addr,lpString
.if eax != INADDR_NONE
mov dwIP,eax
.endf
lpString参数指向“aa.bb.cc.dd”类型的IP地址字符串。如果转换成功,函数将返回已经按网络字节顺序排列的32位IP地址,否则返回INADDR_NONE。
inet_ntoa则是inet_addr函数的逆函数,它将一个网络字节顺序的32位IP地址转换成字符串:
invoke inet_ntoa,in
.if eax
mov lpsz,eax
.endif
参数in是需要转换的32位IP地址,如果转换失败函数返回NULL,转换成功的话函数返回一个指针,指向转换后的IP地址字符串。这个字符串位于WinSock接口的内部缓冲区中,所以若以后需要继续使用的话,那么在调用下一个WinSock函数之前必须将它拷贝到程序自己定义的缓冲区中。
除了IP地址转换函数,WinSock接口还提供了一系列的字节顺序转换函数。
htons函数完成的功能是“Host to Network Short”,即将16位的以当前主机字节顺序排列的数据转换成按网络顺序排列的数据:
invoke htons,hostshort
mov netshort,ax
函数的输入值是按主机字节顺序排列的16位数据(当然需要扩展到32位以便当做参数输入),返回值的低16位是转换后的按网络字节顺序排列的数据。
htonl函数完成的功能是“Host to Network Long”,即将32位的以当前主机字节顺序排列的数据转换成按网络顺序排列的数据:
invoke htonl,hostlong
mov netlong,eax
ntohs函数完成的功能是“Network to Host Short”,即将16位的按网络顺序排列的数据转换成以当前主机字节顺序排列的数据(输入参数同样需要首先被扩展到32位):
invoke ntohs,netshort
mov hostshort,ax
ntohl函数则完成“Network to Host Long”功能,即将32位的按网络顺序排列的数据转换成以当前主机字节顺序排列的数据:
invoke ntohl,netlong
mov hostlong,eax
一般来说,当涉及当前主机字节顺序和网络顺序数据的转换时,不管当前主机使用的字节顺序是否和网络顺序相同,最好都进行一次转换,而且转换时必须使用这些WinSock函数而不是自定义的函数,这样程序可以在不同的主机上进行移植。
比如,现在使用的是Intel 80x86平台,它的字节顺序和网络字节顺序是不一样的,如果使用自定义的函数将字节顺序反过来,万一Windows移植到和网络字节顺序一致的硬件平台上,转换的结果就不对了,但使用WinSock接口提供的转换函数肯定是正确的,所以永远使用WinSock接口提供的转换函数是有必要的。
反之,在运行于Motorola平台上的UNIX系统中,CPU字节顺序和网络字节顺序是相同的,如果程序因此取消了字节顺序转换这一步骤,那么程序移植到运行于Intel平台上的Linux系统中时就会出错,所以不管主机的字节顺序是否和网络字节顺序相同,应该总是使用转换函数进行字节顺序转换。
读者可以注意到Win32 API函数的名称一般由几个单词组成,每个单词的首字母是大写的,但是一部分WinSock函数如socket和ioctlsocket等的命名却是全部小写的,造成这种现象的原因是这些函数名称源于UNIX socket,而UNIX socket中的函数命名全部是小写的。读者也可以注意到:WinSock接口中由Windows系统扩展的函数使用的就是标准的Win32 API命名方式,如WSAStartup和WSAAsyncSelect等。从这里也可以看出哪些函数是WinSock接口特有的。
上页:第16章 TCP/IP和网络通信 · 16.2 WinSock接口(3) 下页:第16章 TCP/IP和网络通信 · 16.3 TCP协议编程(1)