WSAAsyncSelect模型允许以windows消息作为网络事件的通知,这个模型是为了windows消息专门而设置的。这个函数默认使socket为非阻塞模式(一般情况下,异步模式便为非阻塞模式)。当WSAAsyncSelect函数进行调用了以后,就可以在在窗口函数以windows消息的形式接收网络事件通知。LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)是对应的回调函数。
USHORT nPort=4567;
SOCKET sListen=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
socketaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(nPort);
sin.sin_addr.S_un.S_addr=INADDR_ANY;
//绑定套接字到本地机器
if(::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
printf("Failed bind()\n");
return -1;
}
//将套接字设为窗口通知消息类型
::WSAAsyncSelect(sListen,hWnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE);
::listen(sListen,5);
//从消息队列中取出消息
MSG msg;
while(::GetMessage(&msg,NULL,0,0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
swithc(uMsg)
{
case WM_SOCKET:
{
SOCKET s=wParam;
//查看是否出错
if(WSAGETSELECTERROR(lParam))
{
::closesocket(s);
return 0;
}
//处理发生的事件
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
{
SOCKET client=::accept(s,NULL,NULL);
::WSAAsyncSelect(client,hWnd,WM_SOCKET,FD_READ|FD_WRITE|FD_CLOSE);
}
break;
case FD_WRITE:
{}
break;
case FD_READ:
{
char szText[1024]={0};
if(::recv(s,szText,1024,0)==-1)
::closesocket(s);
else
printf(""接收数据:%s",szText);
}
break;
case FD_CLOSE:
{
::closesocket(s);
}
break;
}
}
}
}