Winsock是Windows下的网络编程接口,在VS中可以使用WinSock API开发网络应用程序,实现计算机之间的通信。
构建WinSock应用程序框架
WinSock包含两个主要的版本,WinSock1和WinSock2。使用WinSock1时需要导入头文件winscok.h和winsok32.lib,使用WinSock2时,需要导入winsock2.h和ws2_32lib.
下面是WinSock2.2实现网络通信的应用程序框架:
#include <WinSock2.h>
#pragma comment(lib,"WS2_32.lib")
int _tmain(int argc,_TCHAR* argv[])
{
//初始化WindowsSocket
WSADATA wsdData;
//初始化Socket动态库
if(WSAStartup(MAKEWORD(2,2),&wsdData)!=0){
printf("WSAStartup Failed!\n");
return -1;
}
//使用WinSock实现网络通信
//......
//释放socket
if(SOCKET_ERROR == WSACleanup())
printf("WSACleanup failed!\n");
return 0;
}
结构体WSADATA用来存储调用WSAStartup()后返回的Windows Socket数据。定义如下:
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
#ifdef _WIN64
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
#else
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
#endif
} WSADATA, FAR * LPWSADATA;
WSAStartup()函数用于初始化Windows Sockets,并返回WSADATA结构体。只有调用了这个函数后,才能调用其他Windows Sockets API函数,实现网络通信。WSAStartup()原型如下:
int WSAStartup(
__in WORD wVersionRequested, /*WinSock版本*/
__out LPWSADATA lpWSAData /*指向WSADATA结构体的指针*/
);
IP地址的表现形式
对于网络管理员或者普通用户,IP地址通常用点分十进制表示。但是计算机中,为了不浪费存储空间,使用无符号长整数来存储和表示IP地址,而且分为网络字节顺序(Network Byte Order,NBO)和主机字节顺序(Host Byte Order,HBO)。TCP/IP规定,在低位存储地址中保存数据的高位字节,这种存储方式被称为网络字节顺序。不同类型,不同操作系统的设备在发送数据前必须将二进制数据转换为网络字节顺序。
C++中采用in_addr来保存网络字节顺序格式的IP地址,它的定义代码如下:
typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b; /*由4个u_char变量组成的主机格式IP地址*/
struct { USHORT s_w1,s_w2; } S_un_w; /*由2个u_short变量组成的主机格式IP地址*/
ULONG S_addr; /*由u_long变量表示的主机格式IP地址*/
} S_un;
使用inet_addr()和inet_ntoa()两个函数可实现点分法IP地址字符串和网络字节字符顺序格式IP地址的转换。
inet_addr():将点分法IP转换为in_addr结构体中的IP地址格式,原型:
unsign long inet_addr(
const char FAR * cp
);
inet_addr():将in_addr结构体中的IP地址格式转换为点分法IP,原型:
char FAR* inet_ntoa(
__in struct in_addr in
);
主机字节顺序格式
不同主机对IP地址进行存储时使用的格式也不同。有的和网络字节顺序相同,有的与网络字节顺序相反。Intel x86系列主机字节顺序刚好与网络字节顺序相反。
可以使用htonl()、htons()、ntohl()、ntohs()四个函数实现主机字节顺序和网络字节顺序格式之间的转换。
u_long格式的主机字节转网络字节:
u_long htonl(
u_long hostlong
);
u_short格式的主机字节转网络字节:
u_short htons(
u_short hostshort
);
u_long格式的网络字节转主机字节:
u_long ntohl(
u_long netlong
);
u_short格式的网络字节转主机字节:
u_short ntohs(
u_short netshort
);