服务器的初始化包括全局变量和Windows Sockets动态库的初始化两个部分。
1.初始化全局变量
该服务器程序是Win32 Console Application程序。在程序中使用了一些全局变量,其中包括以下几方面。
q bufRecv:读缓冲区。
q bufSend:写缓冲区。
q sServer:服务器监听套接字。
q sClient:接受客户端套接字。
q bConning:与客户端的连接状态变量。
InitMember()函数实现服务器全局变量的初始化。包括设置读写缓冲区数据为零。初始化服务器监听套接字和接受客户端套接字为INVALID_SOCKET。设置与客户端的连接状态为FALSE。
InitMember()函数程序清单如下。
/*
* 初始化成员变量
*/
void InitMember(void)
{
//初始化读和写缓冲区
memset(bufRecv, 0, MAX_NUM_BUF);
memset(bufSend, 0, MAX_NUM_BUF);
//初始化
sServer = INVALID_SOCKET;
sClient = INVALID_SOCKET;
//没有连接状态
bConning = FALSE;
}
2.Windows Sockets动态库的初始化
WSAStartup()函数实现初始化Windows Sockets动态库的功能。该函数wVersionRequested参数,为调用者使用的Windows Sockets API的最高版本号。wsaData参数用来接收Windows Sockets实现的细节。该函数使得调用方和Windows Sockets DLL之间互相通知对方可以支持的最高版本,以及互相确认对方的最高版本是可接受的。当该函数返回时,wsaData输出参数的wVersion值,指示了应用程序将使用的最终版本。
在该程序中,希望使用Windows Sockets 1.1版本。当WSAStartup()函数返回时,通过下面的程序清单确保Windows Sockets DLL支持1.1版本。
#define SERVER_DLL_REEOR 1 //调用Windows sockets DLL失败
//初始化Windows Sockets DLL
wVersionRequested = MAKEWORD(1,1);
retVal = WSAStartup(wVersionRequested, &wsaData);
if ( 0 != retVal )
{
ShowSocketMsg("Can not find a usable Windows Sockets dll!");
return SERVER_DLL_REEOR;
}
//确保WinSock DLL支持1.1
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1)
{
ShowSocketMsg("Can not find a usable Windows Sockets dll!");
WSACleanup( );
return SERVER_DLL_REEOR;
}
调试wsaData变量,得到图4.9所示的信息。
q 希望调用者使用Windows Sockets 1.1版本。
q DLL可支持Windows Sockets的最高版本为2.2。
q 该Windows Sockets DLL为“Winsock 2.0”。
q 当前DLL处于“Running”状态。
q 一个进程可以打开的最多32767个套接字(Windows Sockets 2.0及以后版本中忽略此值)。
q 该应用程序发送或接收的最大为65467字节的UDP数据报(Windows Sockets 2.0及以后版本中忽略此值)。
q 厂商专有信息(Windows Sockets 2.0及以后版本中忽略此值)。
当调用WSAStartup()失败时,ShowSocketMsg()函数用于显示错误信息。
在使用WSAStartup()函数时需要注意以下三点。
(1)该函数是开发Windows Sockets应用程序时,必须第一个调用的Windows Sokckets API。只有该函数成功返回才能进行后续Windows Sockets API调用。
(2)在Windows Sockets应用程序中可以多次调用该函数。对应于每次WSAStartup()函数的调用,必须有一个WSACleanup()函数调用相匹配。
(3)当该函数调用失败时,通过调用WSAGetLastError()函数,获得的错误代码是不能使用的。