您的位置:首页 > 其它

基于事件I/O模型的socket通信

2014-05-09 20:39 274 查看
WSADATA wsd;//WSADATA变量
SOCKET _socket;
sockaddr_in _addr;
//初始化套结字动态库
//创建
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
WSACleanup();
return;
}

if((_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
{
closesocket(_socket);
WSACleanup();
return;
}

//服务器地址
_addr.sin_family=AF_INET;
_addr.sin_port=htons(5050);                  //端口
_addr.sin_addr.s_addr=INADDR_ANY;             //系统分配ip

//绑定
if(bind(_socket,(SOCKADDR*)&_addr,sizeof(_addr))==SOCKET_ERROR)
{
closesocket(_socket);
WSACleanup();
return;
}

SOCKET sockets[WSA_MAXIMUM_WAIT_EVENTS];// Maximum number of wait objects 64
WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS];

WSAEVENT newEvent;
WSANETWORKEVENTS netWorkEvent;
int eventTotal=0;
int index;

newEvent=WSACreateEvent();
WSAEventSelect(_socket,newEvent,FD_ACCEPT|FD_CLOSE);//_socket为自定义的SOCKET,即服务器端的套接字

listen(_socket,20);//监听
sockets[eventTotal]=_socket;
events[eventTotal]=newEvent;
++eventTotal;

while(true)
{
index=WSAWaitForMultipleEvents(eventTotal,events,false,WSA_INFINITE,false);
index-=WSA_WAIT_EVENT_0;//WSA_WAIT_EVENT_0其实是=0的,此处得到的是发生I/O的socket索引
WSAEnumNetworkEvents(sockets[index],events[index],&netWorkEvent);

if(netWorkEvent.lNetworkEvents&FD_ACCEPT)//新的链接请求
{
if(netWorkEvent.iErrorCode[FD_ACCEPT_BIT] != 0)
std::cout<<"FD_ACCEPT failed with error "<<netWorkEvent.iErrorCode[FD_ACCEPT_BIT]<<"\n";
else
{
sockaddr_in addr;
int l=sizeof(sockaddr_in);
SOCKET accpetSocket=::accept(_socket,(sockaddr*)&addr,&l);
if(eventTotal>=WSA_MAXIMUM_WAIT_EVENTS)
{
std::cout<<"too many connection\n";
closesocket(accpetSocket);
}else
{
std::cout<<"new connection at "<<accpetSocket<<"\n";
newEvent=WSACreateEvent();
WSAEventSelect(accpetSocket,newEvent,FD_READ|FD_CLOSE);//只监听读和关闭事件
sockets[eventTotal]=accpetSocket;
events[eventTotal]=newEvent;
++eventTotal;
}
}
}else if(netWorkEvent.lNetworkEvents&FD_READ)//客户端数据请求
{
std::cout<<"recv data from index "<<index<<"\n";
conduct(sockets[index]);//自定义的处理读取时间的代码,要替换成自己的代码
}else if(netWorkEvent.lNetworkEvents&FD_CLOSE)//客户端关闭请求
{
std::cout<<"close connection from index "<<index<<"\n";
//移除关闭的socket
<div style="text-indent: 28px;"></div>			closesocket(sockets[index]);WSACloseEvent(events[index]);
for(int i=index;i<eventTotal-1;++i)
{
sockets[i]=sockets[i+1];
events[i]=events[i+1];
}
--eventTotal;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: