利用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

相关文章

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

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

Pandas进行周期与时间戳转换的方法

《Pandas进行周期与时间戳转换的方法》本教程将深入讲解如何在pandas中使用to_period()和to_timestamp()方法,完成时间戳与周期之间的转换,并结合实际应用场景展示这些方法的... 目录to_period() 时间戳转周期基本操作应用示例to_timestamp() 周期转时间戳基

Java使用Stream流的Lambda语法进行List转Map的操作方式

《Java使用Stream流的Lambda语法进行List转Map的操作方式》:本文主要介绍Java使用Stream流的Lambda语法进行List转Map的操作方式,具有很好的参考价值,希望对大... 目录背景Stream流的Lambda语法应用实例1、定义要操作的UserDto2、ListChina编程转成M

利用python实现对excel文件进行加密

《利用python实现对excel文件进行加密》由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,本文将以Python语言为例,和大家讲讲如何对Excel文件进行加密,感兴... 目录前言方法一:使用pywin32库(仅限Windows)方法二:使用msoffcrypto-too

Pandas使用AdaBoost进行分类的实现

《Pandas使用AdaBoost进行分类的实现》Pandas和AdaBoost分类算法,可以高效地进行数据预处理和分类任务,本文主要介绍了Pandas使用AdaBoost进行分类的实现,具有一定的参... 目录什么是 AdaBoost?使用 AdaBoost 的步骤安装必要的库步骤一:数据准备步骤二:模型

使用Pandas进行均值填充的实现

《使用Pandas进行均值填充的实现》缺失数据(NaN值)是一个常见的问题,我们可以通过多种方法来处理缺失数据,其中一种常用的方法是均值填充,本文主要介绍了使用Pandas进行均值填充的实现,感兴趣的... 目录什么是均值填充?为什么选择均值填充?均值填充的步骤实际代码示例总结在数据分析和处理过程中,缺失数

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

通过Spring层面进行事务回滚的实现

《通过Spring层面进行事务回滚的实现》本文主要介绍了通过Spring层面进行事务回滚的实现,包括声明式事务和编程式事务,具有一定的参考价值,感兴趣的可以了解一下... 目录声明式事务回滚:1. 基础注解配置2. 指定回滚异常类型3. ​不回滚特殊场景编程式事务回滚:1. ​使用 TransactionT

Java中使用Hutool进行AES加密解密的方法举例

《Java中使用Hutool进行AES加密解密的方法举例》AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个,下面:本文主要介绍Java中使用Hutool进行AES加密解密的相关资料... 目录前言一、Hutool简介与引入1.1 Hutool简介1.2 引入Hutool二、AES加密解密基础

SpringSecurity6.0 如何通过JWTtoken进行认证授权

《SpringSecurity6.0如何通过JWTtoken进行认证授权》:本文主要介绍SpringSecurity6.0通过JWTtoken进行认证授权的过程,本文给大家介绍的非常详细,感兴趣... 目录项目依赖认证UserDetailService生成JWT token权限控制小结之前写过一个文章,从S