标题：WSAStartup
WSAStartup
简介WSAStartup，即WSA(Windows SocKNDs Asynchronous，Windows异步套接字)的启动命令。是Windows下的网络编程接口软件Winsock1 或 Winsock2 里面的一个命令（Ps：Winsock 是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口）。详细说明为了在应用程序当中调用任何一个Winsock API函数，首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化，因此需要调用WSAStartup函数。使用Socket的程序在使用Socket之前必须调用WSAStartup函数。该函数的第一个参数指明程序请求使用的Socket版本，其中高位字节指明副版本、低位字节指明主版本；操作系统利用第二个参数返回请求的Socket的版本信息。当一个应用程序调用WSAStartup函数时，操作系统根据请求的Socket版本来搜索相应的Socket库，然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
函数定义
int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData )；wVersionRequested 
⑴ wVersionRequested：一个WORD（双字节）型数值，在最高版本的Windows Sockets支持调用者使用，高阶字节指定小版本(修订本)号,低位字节指定主版本号。
⑵lpWSAData 指向WSADATA数据结构的指针，用来接收Windows Sockets[1]实现的细节。
WindowsSockets API提供的调用方可使用的最高版本号。高位字节指出副版本(修正)号，低位字节指明主版本号。
注释
本函数必须是应用程序或DLL调用的第一个Windows Sockets函数。它允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节。应用程序或DLL只能在一次成功的WSAStartup()调用之后才能调用进一步的Windows Sockets API函数。
为支持日后可能和Windows Sockets 1.1有功能上差异的Windows Sockets实现及应用程序，在WSAStartup()中规定了一个协议。WSAStartup()的调用方和Windows Sockets DLL互相通知对方它们可以支持的最高版本，并且互相确认对方的最高版本是可接受的。在WSAStartup()函数的入口，Windows Sockets DLL检查了应用程序所需的版本。如果所需版本低于DLL支持的最高版本，则调用成功并且DLL在wHighVersion中返回它所支持的最高版本，在
wVersion中返回它的高版本和wVersionRequested中的较小者。然后Windows Sockets DLL就会假设应用程序将使用wVersion.如果WSDATA结构中的wVersion域对调用方来说不可接收，它就应调用WSACleanup()函数并且要么去另一个Windows Sockets DLL中搜索，要么初始化失败。
本协议允许Windows Sockets DLL和Windows Sockets应用程序共同支持一定范围的Windows Sockets版本。如果版本范围有重叠，应用程序就可以成功地使用Windows Sockets DLL。下列的图表给出了WSAStartup()在不同的应用程序和Windows Sockets DLL版本中是如何工作的：
应用程序版本 DLL版本 wVersionRequested wVersion wHighVersion 最终结果
1.1 1.1 1.1 1.1 1.1 use 1.1
1.0 1.1 1.0 1.1 1.0 1.0 use 1.0 
1.0 1.0 1.1 1.0 1.0 1.1 use 1.0
1.1 1.0 1.1 1.1 1.1 1.1 use 1.1
1.1 1.0 1.1 1.0 1.0 失败
1.0 1.1 1.0 －- －- WSAVERNOTSUPPORTED
1.0 1.1 1.0 1.1 1.1 1.1 1.1 use 1.1
1.1 2.0 1.1 2.0 1.1 1.1 use 1.1
2.0 1.1 2.0 1.1 1.1 失败
下列代码段给出了只支持Windows Sockets 1.1版本的应用程序是如何进行WSAStartup()调用的：
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested =MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
return;
}
/* Confirm that the Windows Sockets DLL supports 1.1.*/
/* Note that if the DLL supports versions greater */
/* than 1.1 in addition to 1.1, it will still return */
/* 1.1 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
WSACleanup( );
return;
}
/* The Windows Sockets DLL is acceptable. Proceed. */
下面的代码段示例了只支持1.1版的Windows Sockets DLL是如何进行WSAStartup()协商的：
/* Make sure that the version requested is >= 1.1. */
/* The low byte is the major version and the high */
/* byte is the minor version. */
if ( LOBYTE( wVersionRequested ) < 1 ||
( LOBYTE( wVersionRequested ) == 1 &&
HIBYTE( wVersionRequested ) < 1 ) {
return WSAVERNOTSUPPORTED;
}
/* Since we only support 1.1, set both wVersion and */
/* wHighVersion to 1.1. */
lpWsaData->wVersion = MAKEWORD( 1, 1 );
lpWsaData->wHighVersion = MAKEWORD( 1, 1 );
一旦应用程序或DLL进行了一次成功的WSAStartup()调用，它就可以继续进行其它所需的Windows Sockets API调用。当它完成了使用该Windows Sockets DLL的服务后，应用程序或DLL必须调用WSACleanup()以允许Windows Sockets DLL释放任何该应用程序的资源。
实际的Windows Sockets实现细节在WSAData结构中描述如下:
struct WSAData {
WORD wVersion;
WORD wHighVersion;
char 
szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYSSTATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
};
返回值
0 成功。
否则返回下列的错误代码之一。注意通常依靠应用程序调用WSAGetLastError()机制获得的错误代码是不能使用的，因为Windows Sockets DLL可能没有建立“上一错误”信息储存的客户数据区域。
关于Windows Sockets提供者的说明：
每一个Windows Sockets应用程序必须在进行其它Windows Sockets API调用前进行WSAStartup()调用。这样，本函数就可以用于初始化的目的。
进一步的说明在WSACleanup()的说明中有讨论。
错误代码
WSASYSNOTREADY 指出网络通信依赖的网络子系统还没有准备好。
WSAVERNOTSUPPORTED 所需的Windows Sockets API的版本未由特定的Windows Sockets实现提供。
WSAEINVAL 应用程序指出的Windows Sockets版本不被该DLL支持。