Visual C++网络编程(黑客)学习笔记五
当客户端向服务器端发出连接请求,服务器端即可用accept函数实现与客户
端的连接。为了达到服务器端的Socket在恰当的时候与从客户端发出来的连
接请求建立连接,服务器端需要使用WSAAsyncSelect函数让系统主动来通
知服务器端程序有客户端提出连接请求了。函数调用成功则返回0,失败则
返回SOCKET_ERROR。
WSAAsyncSelect函数原型:
int WSAAsyncSelect(
SOCKET s,
HWND hWnd,
unsigned int wMsg,
long lEvent
);
函数参数解释:
s:Socket对象。
hWnd:接收消息的窗口句柄。
wMsg:传给窗口的消息。
lEvent:被注册的网络事件,即是应用程序向窗口发送消息的网络事件。
lEvent值为下列值:
FD_READ,FD_WRITE,FD_OOB,FD_ACCEPT,FD_CONNECT,FD_CLOSE的组合
。各个值的具体含义如下:
FD_READ:希望在套接字S收到数据时收到消息。
FD_WRITE:希望在套接字S发送数据时收到消息。
FD_ACCEPT:希望在套接字S收到连接请求时收到消息。
FD_CONNECT:希望在套接字S连接成功时收到消息。
FD_CLOSE:希望在套接字S连接关闭时收到消息。
FD_OOB:希望在套接字S收到带外数据时收到消息。
该函数在具体应用时,wMsg应是在应用程序中定义的消息名称,而消息结
构中的lParam则为以上各种网络事件的名称。所以可在窗口处理自定义消
息函数中使用以下结构代码来响应Socket的不同事件,代码如下:
switch(lParam)
{
//响应FD_READ的函数方法实现
case FD_READ:
...
break;
//响应FD_WRITE的函数实现方法
case FD_WRITE:
...
break;
//响应FD_ACCEPT的函数实现方法
case FD_ACCEPT:
...
break;
//...
}
结束服务器端与客户端的通信连接,可由服务器端或者客户端的任一端发出
请求,只要调用closesocket()就可以了。同样,要关闭服务器端监听状态的
Socket也是利用该函数。在调用closesocket()函数关闭Socket之前,与程序
启动时调用WSAStartup()函数相对应。程序结束前需要调用WSACleanup()
来通知Winsock Stack释放Socket所占用的资源。该函数调用成功返回0 ,
否则返回SOCKET_ERROR.
WSAStartup()函数原型:
int WSAStartup();
该函数在应用程序完成对请求的Socket库的使用后调用,来解除与Socket库
的绑定并且释放Socket库所占用的资源。该函数一般用在网络程序结束的地
方调用。
closesocket()原型:
int closesocket(
SOCKET s
);
函数参数解释:
s:表示要关闭的套接字。
函数成功执行返回0,否则返回SOCKET_ERROR.
每个进程中都有一个套接字描述符表,表中的每个套接字描述符都对应了一
个位于操作系统缓冲区中的套接字数据结构。因此可能有几个套接字描述符
指向同一个套接字数据结构。套接字数据结构中专门有一个字段存放该结构
被引用的次数,即有多少个套接字描述符指向该结构。当调用closesocket
函数时,操作系统先检查套接字数据结构中的该字段的值。如果值为1就表
示只有一个套接字描述符指向它,因此操作系统就先s在套接字描述符表中
对应的那条表项清除,并且释放s对应的套接字数据结构;如果该字段值大
于1,那么操作系统仅仅清除s在套接字描述符表中的对应表项,并且把s对
应的套接字数据结构的引用次数减1.
