Winsock网络编程Winsock动态库初始化

每个Winsock应用程序必须导入合适版本的Winsock DLL。如果在调用Winsock函数之前导入库函数失败,则函数会返回SOCKET_ERROR,该错误值是WSANOTINITIALISED。通过调用WSAStartup()函数来导入Winsock库文件。

1 WSAStartup()函数

WSAStartup()函数的格式如下所示

int WSAStartup( WORD wVersionRequired, LPWSADATA lpWSAData );

其中,wVersionRequired用来指定要导入的Winsock库文件的版本号;高阶字节指定了版本号中较小的数字(小数点之后的数字),低阶字节指定了版本号中较大的数字(小数点之前的数字)。可以使用MAKEWORD(x,y)宏来创建Winsock的版本号,其中x表示高阶字节,而y表示低阶字节。lpWSAData是WSADATA结构的指针,该参数在调用WSAStartup()函数后会将其成员变量进行填充。

2 WSADATA结构

WSADATA结构定义如下所示

typedef struct WSAData {

WORD wVersion;

WORD wHighVersion;

unsigned short iMaxSockets;

unsigned short iMaxUdpDg;

char *lpVendorInfo;

char szDescription[WSADESCRIPTION_LEN + 1];

char szSystemStatus[WSASYS_STATUS_LEN + 1];

} WSADATA;

WSAStartup()函数将第一个成员变量wVersion设置为要使用的Winsock的版本号;wHighVersion保存了Winsock库中可以使用的最高的版本号;需要注意的是,这些值中高阶字节表示minor版本号,低阶字节表示major版本号。szDescription和szSystemStatus由Winsock的特殊的实现所设置,并不会被真正使用。不要使用iMaxSockets和iMaxUdpDg这两个域,iMaxSockets表示同时打开套接字的最大数量,iMaxUdpDg表示数据报的最大大小。可以通过WSAEnumProtocols()函数来查询数据报的最大大小。同时打开套接字的最大数量不是一个magic number,它依赖于可使用的物理资源。lpVendorInfo为特定的供应商信息,该域不会被任何Windows平台所使用。

3 WSACleanup()函数

当应用程序完成时,需要调用WSACleanup(),该函数允许Winsock来释放所有分配的资源,并且取消所有等待的Winsock调用。

该函数的格式为

int WSACleanup();

如果成功释放了所有资源,则返回值是0;否则返回值是SOCKET_ERROR。

当应用程序退出时,如果调用WSACleanup()失败,则不会有影响,因为操作系统会自动释放这些资源。但是,在调用WSAStartup()之后都要调用WSACleanup()。

4 相关代码

在使用上述代码进行Winsock编程时,需要添加《Winsock网络编程头文件及库文件的设置》中提到的头文件和库文件。

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);

if (err != 0) {

 printf("WSAStartup failed with error: %d\n", err);

 return 1;

}

在初始化Winsock动态库之后,可以对wsaData中的wVersion成员变量进行判断,用来确认加载的Winsock动态库的版本是否是2.2。

 if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)

{

 printf("Could not find a usable version of Winsock.dll\n");

WSACleanup();

return 1;

 }

else

printf("The Winsock 2.2 dll was found okay\n");

WSACleanup();

需要注意的是,即使程序加载的Winsock动态库版本超过2.2,但是由于在WSAStartup()函数中我们已经指定了Winsock动态库所需的版本,此时wVersion中保存仍然是2.2版本。如果Winsock动态库版本低于2.2,则wVersion中保存的是动态库的实际版本号。

最后,程序调用WSACleanup()函数释放网络资源。

你可能感兴趣的:(网络编程)