利用WSAEventSelect进行网络通信

              服务器端代码

      

// Server.cpp : 定义控制台应用程序的入口点。
//


#include<winsock2.h>
#pragma comment(lib,"WS2_32")
#include<stdio.h>


int main()
{
    printf("服务器程序\n");
	//加载动态链接库
	WORD ver=MAKEWORD(2,2);
	WSADATA data;
	if(WSAStartup(ver,&data)!=0)
	{
		printf("WSASTARTUP fail\n");
		return 1;
	}
	else
	{
        printf("加载winsock库成功\n");
	}
	//创建监听套接字
	SOCKET s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	u_long u=1;
	ioctlsocket(s,FIONBIO,&u);
	//绑定套接字
	sockaddr_in Sadd;
	Sadd.sin_family=AF_INET;
	Sadd.sin_port=htons(6000);
	Sadd.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

	if(bind(s,(sockaddr*)&Sadd,sizeof(Sadd))==SOCKET_ERROR)
	{
		printf("failed bind()\n");
		return 1;
	}
	else
	{
		printf("绑定成功\n");
	}

	//监听状态
	if(listen(s,5)==SOCKET_ERROR)
	{
        printf("监听失败\n");
		return 1;
	}
	else
	{
		 printf("监听成功\n");
	}

	//创建事件对象
    WSAEVENT newEvent=WSACreateEvent();
	if(newEvent==WSA_INVALID_EVENT)
	{
	   printf("创建事件对象失败\n");
	   return 1;
	}
	else 
	{
		 printf("创建事件对象成功\n");
	}

	//网络事件注册
    int err=WSAEventSelect(s,newEvent,FD_ACCEPT|FD_CLOSE);
    if(err==INVALID_SOCKET)
	{
		printf("注册网络事件失败\n");
		return 1;
	}
	
	//准备工作
	int t=1;
	WSAEVENT eventArray[10];
	SOCKET sockArray[10];
	int n=0;
    eventArray[n]=newEvent;
    sockArray[n]=s;
	n++;

	//循环处理
	while(true)
	{
		int index=WSAWaitForMultipleEvents(n,eventArray,false,4000,false);
		printf("index=%d\n",index);

		if(index==WSA_WAIT_FAILED)
		{
           printf("调用失败\n");
		   break;
		}
		else if(index==WSA_WAIT_TIMEOUT)
		{
           if(t<3)
		   {
			   printf("第%d次超时",t);
			   t++;
			   continue;
		   }
		   else
		   {
			   printf("第%d次超时,退出",t);
			   break;
		   }
		}
		else
		{
            WSANETWORKEVENTS events;  //记录网络事件出错的代码
			//网络事件查询
			WSAEnumNetworkEvents(sockArray[index],NULL,&events);
			WSAResetEvent(eventArray[index]);

			//处理accept消息
			if((events.lNetworkEvents & FD_ACCEPT)!=0)
			{
				if(events.iErrorCode[FD_ACCEPT_BIT]==0)
				{
					if(n>10)
					{
						printf("连接已经饱满\n");
						break;
					}
					printf("有连接请求到来\n");
					SOCKET sNew=accept(sockArray[index],NULL,NULL);
                    newEvent=WSACreateEvent();
					WSAEventSelect(sNew,newEvent,FD_READ|FD_WRITE|FD_CLOSE);
                    
					eventArray[n]=newEvent;
                    sockArray[n]=sNew;

					n++;
					printf("socket %d connect\n",sNew);
				}
			}
		   if(events.lNetworkEvents& FD_READ)
		   {
               if(events.iErrorCode[FD_READ_BIT]==0)
			   {
				   char buf[256]={0};
				   int num=recv(sockArray[index],buf,sizeof(buf),0);
				   if(num>0)
				   {
					   printf("接收到客户端%d的数据:%s\n",sockArray[index],buf);
				   }
			   }
		   }
		   if(events.lNetworkEvents& FD_CLOSE)
		   {
			   if(events.iErrorCode[FD_CLOSE_BIT]==0)
			   {
                   printf("套接字为%d的已关闭连接\n",sockArray[index]);
			   }
			   else
			   {
				   if(events.iErrorCode[FD_CLOSE_BIT]==10053)
				   {
					   printf("客户端%d非法关闭\n",sockArray[index]);
				   }
			   }

			   for(int j=index;j<n-1;j++)
			   {
                   eventArray[j]=eventArray[j+1];
                   sockArray[j]=sockArray[j+1];
			   }
			   n--;
		   }

		}
	}
	return 0;
}
客户端代码


//Client 1
#include <winsock2.h>
#pragma comment(lib,"WS2_32")
#include <stdio.h>
int main()
{  	printf("客户端程序\n"); 	
//----------------①加载---------------------------------------------------------
    WSADATA wsaData;
    WORD wVersionRequested=MAKEWORD(2,2);  
	if(WSAStartup(wVersionRequested,&wsaData)!=0)  			
	{   printf("WSAStartup() Failed,Error=\n",WSAGetLastError());	
		return 1;
	}
	else 
		printf("①加载成功\n");		
//----------------②创建流式套节字------------------------------------------------	
	SOCKET c1;
	c1 = socket(AF_INET, SOCK_STREAM,0);
	if(c1 == INVALID_SOCKET)	
	{   printf("socket() Failed,Error=\n",WSAGetLastError());
		return 1;
	}
	else 
		printf("②已创建连接套接字:【 %d 】\n",c1);	
//----------------绑定本地地址------------------------------------------------
    struct  sockaddr_in  C1add;  
    C1add.sin_family=AF_INET;
	C1add.sin_port=htons(2222);
	C1add.sin_addr.s_addr=inet_addr("127.0.0.1");	
	if(bind(c1,(sockaddr*)&C1add,sizeof(C1add))==SOCKET_ERROR)	
	{   printf("bind() Failed,Error=\n",WSAGetLastError());	
		return 1;
	}
	else 
		printf("绑定成功,本地IP地址:【 %s 】,端口号:【 %d 】\n",inet_ntoa(C1add.sin_addr),ntohs(C1add.sin_port));	
//------------------③连接请求------------------------------------------------		
	struct  sockaddr_in  Sadd;  
	Sadd.sin_family=AF_INET;
	Sadd.sin_port=htons(6000);  
	Sadd.sin_addr.s_addr=inet_addr("127.0.0.1");		
	if(connect(c1, (sockaddr*)&Sadd, sizeof(Sadd)) == -1)
	{   printf(" Failed connect(),Error=【 %d 】\n",WSAGetLastError());		
		return 1;
	}
	else //*************************连接成功,可以 开始发送、接收*************************
	{	printf("③连接成功,服务器IP地址:【 %s 】,端口号:【 %d 】\n",inet_ntoa(Sadd.sin_addr),ntohs(Sadd.sin_port));
	    int a;
	    printf("希望发送数据吗?(键入“1”发送)");
		scanf("%d",&a);	 			
	    while(a==1)  //------循环处理------
		{   //-----发送------     			    
            char S_buf[] = "Hello!I am a client 1";	
		    int  isend=send(c1,S_buf,strlen(S_buf),0);		
		    if(isend==SOCKET_ERROR)	
			{  printf("Failed  send(),Error=【 %d 】,或者服务器意外关闭\n",WSAGetLastError());
		   	   return 1;
			}
		    else if(isend!=0)
			   printf("信息【 %s 】已发送\n",S_buf);			 
		    else
			   printf("信息无法发送给服务端\n");

			printf("希望继续发送数据吗?(键入“1”继续发送)");
				scanf("%d",&a);
    	        if(a!=1)			
		        break;
		} //------end 循环处理------	   
	} //*************************end 开始发送、接收*************************
//------------------④关闭、释放------------------------------------------------	
    closesocket(c1);		
	WSACleanup();
	printf("④与服务器连接完毕\n");
	return 0;
	
}






你可能感兴趣的:(网络,socket,Stream,服务器,null,events)