//创建服务器端套接字
ServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ServerSock == INVALID_SOCKET)
{
MessageBox("创建套接字失败!");
closesocket(ServerSock);
WSACleanup();
return FALSE;
}
//绑定到本地一个端口上
sockaddr_in localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(8888); //端口号不要与其他应用程序冲突
localaddr.sin_addr.s_addr = 0;
if(bind(ServerSock ,(struct sockaddr*)&localaddr,sizeof(sockaddr))
= = SOCKET_ERROR)
{
MessageBox("绑定地址失败!");
closesocket(ServerSock);
WSACleanup();
return FALSE;
}
//将SeverSock设置为异步非阻塞模式,并为它注册各种网络异步事件,其 中 m_hWnd
//为应用程序的主对话框或主窗口的句柄
if(WSAAsyncSelect(ServerSock, m_hWnd, NETWORK_EVENT,
FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
{
MessageBox("注册网络异步事件失败!");
WSACleanup();
return FALSE;
}
listen(ServerSock, 5);//设置侦听模式
return TRUE;
}
下面定义网络异步事件的回调函数
void CSocketSeverDlg::OnNetEvent(WPARAM wParam, LPARAM lParam)
{
//调用Winsock API函数,得到网络事件类型
int iEvent = WSAGETSELECTEVENT(lParam);
//调用Winsock API函数,得到发生此事件的客户端套接字
SOCKET CurSock= (SOCKET)wParam;
switch(iEvent)
{
case FD_ACCEPT: //客户端连接请求事件
OnAccept(CurSock);
break;
case FD_CLOSE: //客户端断开事件:
OnClose(CurSock);
break;
case FD_READ: //网络数据包到达事件
OnReceive(CurSock);
break;
case FD_WRITE: //发送网络数据事件
OnSend(CurSock);
break;
default: break;
}
}
以下是发生在相应Socket上的各种网络异步事件的处理函数,其中OnAccept传进来的参数是服务器端创建的套接字,OnClose()、OnReceive()和OnSend()传进来的参数均是服务器端在接受客户端连接时新创建的用与此客户端通信的 Socket。
责任编辑:小草