摘自
www.coolsir.org/boxcounter/index.php?id=50
看〈windows网络编程〉时,自己写的最简单的SERVER程序,写的过程中调整了自己对WSAEventSelect模式不少错误理解。
#include <Winsock2.h>
#include <windows.h>
#include <iostream>
using namespace std;
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
//******************************
//变量定义以及初始化
SOCKET sockSrv,
sockCon;
SOCKADDR_IN srvAddr;
WSAEVENT event;
sockSrv = socket(AF_INET,SOCK_STREAM,0);
memset(&srvAddr,0,sizeof(SOCKADDR_IN));
srvAddr.sin_family = AF_INET;
srvAddr.sin_addr.S_un.S_addr = INADDR_ANY;
srvAddr.sin_port = htons(9221);
event = WSACreateEvent();
//******************************
if(SOCKET_ERROR == bind(sockSrv,(SOCKADDR*)&srvAddr,sizeof(SOCKADDR_IN)))
{
cout<<"bind() failure! "<<endl;
return;
}
if(SOCKET_ERROR == listen(sockSrv,10))
{
cout<<"listen() failure!"<<endl;
return;
}
//********************************
//主要代码开始
//监视ACCEPT事件
if(SOCKET_ERROR == WSAEventSelect(sockSrv,event,FD_ACCEPT))
{
cout<<"WSAEventSelect() failure!"<<endl;
return;
}
//创建网络事件,做为WSAEnumNetworkEvents()函数的参数
WSANETWORKEVENTS netEvent;
char buf[100] = {'0'}; //接收buf
for(;;)
{
//等待网络事件
WSAWaitForMultipleEvents(1,&event,TRUE,WSA_INFINITE,FALSE);
WSAEnumNetworkEvents(sockSrv,event,&netEvent);
if(netEvent.lNetworkEvents == FD_ACCEPT)
{
//该网络事件是ACCEPT事件
//接受该连接请求
sockCon = accept(sockSrv,NULL,NULL);
if(INVALID_SOCKET == sockCon)
{
cout<<"accept() failure!"<<endl;
return;
}
//重置event,准备监视READ或WRITE等事件
event = WSACreateEvent();
//开始监视READ事件
if(SOCKET_ERROR == WSAEventSelect(sockCon,event,FD_READ))
{
cout<<"WSAEventSelect() failure!"<<endl;
return;
}
}
//等待网络事件
WSAWaitForMultipleEvents(1,&event,TRUE,WSA_INFINITE,FALSE);
WSAEnumNetworkEvents(sockCon,event,&netEvent);
//该网络事件是READ事件
if(netEvent.lNetworkEvents == FD_READ)
{
recv(sockCon,buf,100,0); //接收client数据
cout<<buf<<endl;
}
}
}