利用WSAEventSelect进行网络通信

2023-12-07 10:32

本文主要是介绍利用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);			 elseprintf("信息无法发送给服务端\n");printf("希望继续发送数据吗?(键入“1”继续发送)");scanf("%d",&a);if(a!=1)			break;} //------end 循环处理------	   } //*************************end 开始发送、接收*************************
//------------------④关闭、释放------------------------------------------------	closesocket(c1);		WSACleanup();printf("④与服务器连接完毕\n");return 0;}


这篇关于利用WSAEventSelect进行网络通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/465531

相关文章

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

使用Python进行GRPC和Dubbo协议的高级测试

《使用Python进行GRPC和Dubbo协议的高级测试》GRPC(GoogleRemoteProcedureCall)是一种高性能、开源的远程过程调用(RPC)框架,Dubbo是一种高性能的分布式服... 目录01 GRPC测试安装gRPC编写.proto文件实现服务02 Dubbo测试1. 安装Dubb

Linux使用scp进行远程目录文件复制的详细步骤和示例

《Linux使用scp进行远程目录文件复制的详细步骤和示例》在Linux系统中,scp(安全复制协议)是一个使用SSH(安全外壳协议)进行文件和目录安全传输的命令,它允许在远程主机之间复制文件和目录,... 目录1. 什么是scp?2. 语法3. 示例示例 1: 复制本地目录到远程主机示例 2: 复制远程主

windows系统上如何进行maven安装和配置方式

《windows系统上如何进行maven安装和配置方式》:本文主要介绍windows系统上如何进行maven安装和配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. Maven 简介2. maven的下载与安装2.1 下载 Maven2.2 Maven安装2.

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

Go语言中使用JWT进行身份验证的几种方式

《Go语言中使用JWT进行身份验证的几种方式》本文主要介绍了Go语言中使用JWT进行身份验证的几种方式,包括dgrijalva/jwt-go、golang-jwt/jwt、lestrrat-go/jw... 目录简介1. github.com/dgrijalva/jwt-go安装:使用示例:解释:2. gi

SpringBoot如何对密码等敏感信息进行脱敏处理

《SpringBoot如何对密码等敏感信息进行脱敏处理》这篇文章主要为大家详细介绍了SpringBoot对密码等敏感信息进行脱敏处理的几个常用方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录​1. 配置文件敏感信息脱敏​​2. 日志脱敏​​3. API响应脱敏​​4. 其他注意事项​​总结

python进行while遍历的常见错误解析

《python进行while遍历的常见错误解析》在Python中选择合适的遍历方式需要综合考虑可读性、性能和具体需求,本文就来和大家讲解一下python中while遍历常见错误以及所有遍历方法的优缺点... 目录一、超出数组范围问题分析错误复现解决方法关键区别二、continue使用问题分析正确写法关键点三

Python对PDF书签进行添加,修改提取和删除操作

《Python对PDF书签进行添加,修改提取和删除操作》PDF书签是PDF文件中的导航工具,通常包含一个标题和一个跳转位置,本教程将详细介绍如何使用Python对PDF文件中的书签进行操作... 目录简介使用工具python 向 PDF 添加书签添加书签添加嵌套书签Python 修改 PDF 书签Pytho

Java进行日期解析与格式化的实现代码

《Java进行日期解析与格式化的实现代码》使用Java搭配ApacheCommonsLang3和Natty库,可以实现灵活高效的日期解析与格式化,本文将通过相关示例为大家讲讲具体的实践操作,需要的可以... 目录一、背景二、依赖介绍1. Apache Commons Lang32. Natty三、核心实现代