(9)下:学习与验证 linux 里的 epoll 对象里的 EPOLLIN、 EPOLLHUP 与 EPOLLRDHUP 的不同。小例子的实验

(4)本实验代码的蓝本,是伊圣雨老师里的课本里的代码,略加改动而来的。
++以下是 服务器端的代码:

在这里插入图片描述

++ 每当收到客户端的报文时,就测试一下对应的 epoll 事件里的事件标志,不读取报文内容,所以设置为 ET 边缘触发模式。
++ 对应的代码版本 :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <fcntl.h> //增加这俩头文件
#include <errno.h>#define EPOLL_SIZE  50int main(int argc,char * argv[])
{   //验证 EPOLLHUP 等标志的服务器端, argc = 2int serv_sock, clnt_sock, str_len, i, epfd, event_cnt;struct sockaddr_in serv_adr, clnt_adr;socklen_t adr_sz;  struct epoll_event event, * ep_events;if(argc != 2) { printf("参数不是2个\n");exit(1); }serv_sock = socket(PF_INET,SOCK_STREAM,0);printf("创建了监听套接字,描述符为: %d\n",serv_sock);memset(&serv_adr,0,sizeof(serv_adr));serv_adr.sin_family = AF_INET; // 协议serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址serv_adr.sin_port = htons(atoi(argv[1])); //端口号bind( serv_sock,(struct sockaddr *)&serv_adr, sizeof(serv_adr) ) ;listen(serv_sock,5);epfd = epoll_create(EPOLL_SIZE); // EPOLL_SIZE = 50event.events  = EPOLLIN; // 监听套接字仍为水平触发模式event.data.fd = serv_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);ep_events = malloc(sizeof(struct epoll_event) * EPOLL_SIZE);while (1) // 此循环在正常情况下是不会退出的。{   event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, -1);       if(-1 == event_cnt) {  break; } // 出错则结束循环,进程退出   puts("从 epoll_wait() 返回了");//统计epoll_wait()的返回次数for(i = 0 ; i < event_cnt ; i++) //依次处理所有发生了事件的套接字{   if(ep_events[i].data.fd == serv_sock)//监听套接字{   adr_sz = sizeof(clnt_adr);clnt_sock = accept( serv_sock,(struct sockaddr *)&clnt_adr,&adr_sz );event.events = EPOLLIN | EPOLLHUP |EPOLLRDHUP | EPOLLET ;// 通信套接字用边缘触发是因为不准备读取报文event.data.fd = clnt_sock; epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event); printf("创建了通信套接字 id: %d\n", clnt_sock);} else { // 依次测试通讯套接字上有事件时具有的 epoll标志。uint32_t revents = ep_events[i].events; int fd = ep_events[i].data.fd;if( revents & EPOLLIN    ) printf("通信套接字 %d 上有 EPOLLIN    事件\n", fd);if( revents & EPOLLHUP   ) printf("通信套接字 %d 上有 EPOLLHUP   事件\n", fd);if( revents & EPOLLRDHUP ) printf("通信套接字 %d 上有 EPOLLRDHUP 事件\n", fd);}} // for(...)  } // while(...)return 0;  
}

(5) 接着给出客户端的版本,这是一个 linux 版本的客户端,很简单的小程序

在这里插入图片描述

++ 记录其源代码版本:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>int main(int argc,char * argv[])
{   // 回声客户端,三个参数,argc = 3int  sock, str_len;  struct sockaddr_in  serv_adr;if(argc != 3) { printf("参数不是3个\n");exit(1); }sock = socket(PF_INET,SOCK_STREAM,0);memset(&serv_adr,0,sizeof(serv_adr));serv_adr.sin_family = AF_INET;// serv_adr.sin_addr.s_addr = inet_addr(argv[1]);// inet_addr() 的语义不明,不好// 处理文本地址,只需使用 inet_pton() 与 inet_ntop() 即可。// int inet_pton(int af, const char *src, void *dst);inet_pton(AF_INET, argv[1], &serv_adr.sin_addr.s_addr);serv_adr.sin_port = htons(atoi(argv[2]));if(connect(sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) != -1)puts("客户端套接字连接至服务器成功\n");sleep(60); // 延迟 60s 以观察实验结果close(sock); // 此行可注释,以验证 四次握手与 RST 报文的出现时机exit(0);
}

(6)后来实验中发现,客户端采用 linux 版本,会导致 wireshark 无法抓包,只好再编写 windows 版本的客户端,源代码如下:

在这里插入图片描述

++ 代码版:

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>#pragma warning(disable : 4996) // 禁用关于 inet_addr 的过时警告int main() 
{WSADATA m_wsadata; // 在 windows平台使用 socket前,须做一下初始化,WSAStartup(0x0202, &m_wsadata); // 最后用 WSACleanup() 释放库。SOCKET sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);SOCKADDR_IN       server_in;memset(&server_in, 0, sizeof(SOCKADDR_IN));  //连接服务器server_in.sin_family = AF_INET;server_in.sin_port = htons(9000); // 连接至 80 端口server_in.sin_addr.s_addr = inet_addr("192.168.1.126");connect(sClient, (struct sockaddr*)&server_in, sizeof(SOCKADDR_IN));for (int i = 0; i < 1000000000; i++); // 延时一下closesocket(sClient); // 关闭套接字的函数WSACleanup();         // 用这个函数关闭库return 0; 
}

++ 使用 windows 的套接字,还要设置一下 vs2019 ,要不然上面的代码会找不到外部函数

在这里插入图片描述

++ 以及:

在这里插入图片描述

(7) 以下给出实验结果,配合 wireshark 抓包

在这里插入图片描述

(8)

谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/11061.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Janus-Pro 论文解读:DeepSeek 如何重塑多模态技术格局

Janus-Pro&#xff1a;多模态领域的璀璨新星——技术解读与深度剖析 一、引言 在人工智能的浩瀚星空中&#xff0c;多模态理解与生成模型犹如耀眼的星座&#xff0c;不断推动着技术边界的拓展。Janus-Pro作为这一领域的新兴力量&#xff0c;以其卓越的性能和创新的架构&#x…

好用的翻译工具

最近看到个好用的翻译工具&#xff0c;叫沉浸式翻译 沉浸式翻译 - 双语对照网页翻译插件 | PDF翻译 | 视频字幕翻译 我下载的是谷歌插件 点击下载插件会跳转到使用文档&#xff0c;跟着一步步操作即可 翻译的效果&#xff0c;我这里用的是免费版的&#xff0c;如果需要加强&…

信息学奥赛一本通 ybt 1608:【 例 3】任务安排 3 | 洛谷 P5785 [SDOI2012] 任务安排

【题目链接】 ybt 1608&#xff1a;【 例 3】任务安排 3 洛谷 P5785 [SDOI2012] 任务安排 【题目考点】 1. 动态规划&#xff1a;斜率优化动规 2. 单调队列 3. 二分答案 【解题思路】 与本题题面相同但问题规模不同的题目&#xff1a; 信息学奥赛一本通 1607&#xff1a…

LabVIEW无线齿轮监测系统

本案例介绍了基于LabVIEW的无线齿轮监测系统设计。该系统利用LabVIEW编程语言和改进的天牛须算法优化支持向量机&#xff0c;实现了无线齿轮故障监测。通过LabVIEW软件和相关硬件&#xff0c;可以实现对齿轮箱振动信号的采集、传输和故障识别&#xff0c;集远程采集、数据库存储…

Doki Doki Mods Maker小指南

-*- 做都做了&#xff0c;那就做到底吧。 -*- 前言&#xff1a; 项目的话&#xff0c;在莫盘里&#xff0c;在贴吧原帖下我有发具体地址。 这里是Doki Doki Mods Maker&#xff0c;是用来做DDLC Mods的小工具。 说是“Mods”&#xff0c;实则不然&#xff0c;这个是我从零仿…

Node.js——body-parser、防盗链、路由模块化、express-generator应用生成器

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

三、js笔记

(一)JavaScript概述 1、发展历史 ScriptEase.(客户端执行的语言):1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言)Javascript:Netscape(网景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigat…

JavaScript作用域详解

前言 作用域是JavaScript中一个重要的概念&#xff0c;它决定了变量和函数在代码中的可访问性和可见性。了解JavaScript的作用域对于编写高效、可维护的代码至关重要。本文将深入介绍JavaScript作用域相关的知识点&#xff0c;其中包括作用域类型&#xff0c;作用域链&#xff…

如何使用SliverList组件

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了沉浸式状态栏相关的内容&#xff0c;本章回中将介绍SliverList组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在这里介绍的SliverList组件是一种列表类组件&#xff0c;类似我们之前介…

vsnprintf() 将可变参数格式化输出到字符数组

vsnprintf{} 将可变参数格式化输出到一个字符数组 1. function vsnprintf()1.1. const int num_bytes vsnprintf(NULL, 0, format, arg); 2. Parameters3. Return value4. Example5. llama.cppReferences 1. function vsnprintf() https://cplusplus.com/reference/cstdio/vs…

一文大白话讲清楚webpack基本使用——17——Tree Shaking

文章目录 一文大白话讲清楚webpack基本使用——17——Tree Shaking1. 建议按文章顺序从头看&#xff0c;一看到底&#xff0c;豁然开朗2. 啥叫Tree Shaking3. 什么是死代码&#xff0c;怎么来的3. Tree Shaking的流程3.1 标记3.2 利用Terser摇起来 4. 具体使用方式4.1 适用前提…

仿真设计|基于51单片机的温湿度、一氧化碳、甲醛检测报警系统

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现&#xff08;protues8.7&#xff09; 程序&#xff08;Keil5&#xff09; 全部内容 资料获取 具体实现功能 &#xff08;1&#xff09;温湿度传感器、CO传感器、甲醛传感器实时检测温湿度值、CO值和甲醛值进…

几种K8s运维管理平台对比说明

目录 深入体验**结论**对比分析表格**1. 功能对比****2. 用户界面****3. 多租户支持****4. DevOps支持** 细对比分析1. **Kuboard**2. **xkube**3. **KubeSphere**4. **Dashboard****对比总结** 深入体验 KuboardxkubeKubeSphereDashboard 结论 如果您需要一个功能全面且适合…

GenAI 在金融服务领域的应用:2025 年的重点是什么

作者&#xff1a;来自 Elastic Karen Mcdermott GenAI 不是魔法 我最近参加了 ElasticON&#xff0c;我们与纽约 Elastic 社区一起度过了一天&#xff0c;讨论了使用检索增强生成 (retrieval augmented generation - RAG) 为大型语言模型 (large language models - LLMs) 提供…

如何对系统调用进行扩展?

扩展系统调用是操作系统开发中的一个重要任务。系统调用是用户程序与操作系统内核之间的接口,允许用户程序执行内核级操作(如文件操作、进程管理、内存管理等)。扩展系统调用通常包括以下几个步骤: 一、定义新系统调用 扩展系统调用首先需要定义新的系统调用的功能。系统…

LightM-UNet(2024 CVPR)

论文标题LightM-UNet: Mamba Assists in Lightweight UNet for Medical Image Segmentation论文作者Weibin Liao, Yinghao Zhu, Xinyuan Wang, Chengwei Pan, Yasha Wang and Liantao Ma发表日期2024年01月01日GB引用> Weibin Liao, Yinghao Zhu, Xinyuan Wang, et al. Ligh…

Cubemx文件系统挂载多设备

cubumx版本&#xff1a;6.13.0 芯片&#xff1a;STM32F407VET6 在上一篇文章中介绍了Cubemx的FATFS和SD卡的配置&#xff0c;由于SD卡使用的是SDIO通讯&#xff0c;因此具体驱动不需要自己实现&#xff0c;Cubemx中就可以直接配置然后生成SDIO的驱动&#xff0c;并将SD卡驱动和…

电子电气架构 --- 汽车电子拓扑架构的演进过程

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 简单&#xff0c;单纯&#xff0c;喜欢独处&#xff0c;独来独往&#xff0c;不易合同频过着接地气的生活…

2025 年,链上固定收益领域迈向新时代

“基于期限的债券市场崛起与Secured Finance的坚定承诺” 2025年&#xff0c;传统资产——尤其是股票和债券——大规模涌入区块链的浪潮将创造历史。BlackRock 首席执行官 Larry Fink 近期在彭博直播中表示&#xff0c;代币化股票和债券将逐步融入链上生态&#xff0c;将进一步…

数据密码解锁之DeepSeek 和其他 AI 大模型对比的神秘面纱

本篇将揭露DeepSeek 和其他 AI 大模型差异所在。 目录 ​编辑 一本篇背景&#xff1a; 二性能对比&#xff1a; 2.1训练效率&#xff1a; 2.2推理速度&#xff1a; 三语言理解与生成能力对比&#xff1a; 3.1语言理解&#xff1a; 3.2语言生成&#xff1a; 四本篇小结…