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

   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;
		}
	}	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值