2023.07.29 驱动开发DAY6

通过epoll实现一个并发服务器

服务器

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>#define ERR_MSG(msg)               \
do {                               \printf("LINE: %d\n", __LINE__);\perror(msg);                   \
} while(0)#define PORT 6666
#define IP "127.0.0.1"int main(int argc,const char * argv[])
{//创建流式套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){ERR_MSG("socket");return -1;}printf("socket create success\n");//允许端口快速复用int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("setsockopt success\n");//填充地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);//将IP地址和端口号绑定到指定的套接字文件描述符上if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success\n");//将通讯套接字设置为被动监听状态if(listen(sfd, 128) < 0){ERR_MSG("listen");return -1;}printf("listen success\n");// 创建epoll句柄int epfd = epoll_create(1);if(epfd < 0){printf("epoll_create filed\n");return -1;}// 添加准备就绪事件进入epoll;struct epoll_event event;struct epoll_event events[10]; //存放就绪事件描述符的数组event.events = EPOLLIN; // 读事件event.data.fd = sfd;if(epoll_ctl(epfd, EPOLL_CTL_ADD, sfd, &event) < 0){printf("epoll_ctl add filed\n");}//监听事件是否发生struct sockaddr_in cin;        //存储客户端信息socklen_t len = sizeof(cin);struct sockaddr_in savecin[1024];int ret, res;char buf[128] = {};while(1){//如果成功,ret接收返回的事件个数,把就绪的事件放在events数组中ret = epoll_wait(epfd, events, 10, -1);if(ret < 0){printf("epoll_wait filed\n");return -1;}//循环遍历数组,做事件处理for(int i=0; i<ret; i++){if(events[i].events & EPOLLIN){if(events[i].data.fd == sfd){//触发客户端连接事件int newfd = accept(sfd, (struct sockaddr*)&cin, &len);if(newfd < 0){ERR_MSG("accpet");return -1;}printf("[%s:%d] 客户端连接成功 newfd=%d\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);savecin[newfd] = cin;//添加新连接客户端进入epoll;event.events = EPOLLIN; // 读事件event.data.fd = newfd;if(epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &event) < 0){printf("epoll_ctl add filed\n");return -1;}}else{//触发客户端交互事件                   //接收数据int cfd = events[i].data.fd;bzero(buf, sizeof(buf));res = recv(cfd, buf, sizeof(buf), 0);if(res < 0){ERR_MSG("recv");return -1;}else if(res == 0){printf("[%s:%d] 客户端下线 cfd=%d\n", inet_ntoa(savecin[cfd].sin_addr), ntohs(savecin[cfd].sin_port), cfd);close(cfd); // 关闭文件描述符//添加断开连接的客户端从epoll中删除;if(epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, NULL) < 0){printf("epoll_ctl del filed\n");return -1;}continue;}printf("[%s:%d] cfd=%d: %s\n", inet_ntoa(savecin[cfd].sin_addr), ntohs(savecin[cfd].sin_port), cfd, buf);// 发送数据strcat(buf, "*_*");if(send(cfd, buf, sizeof(buf), 0) < 0){ERR_MSG("send");return -1;}}}}}return 0;
}

客户端

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define ERR_MSG(msg)               \
do {                               \printf("LINE: %d\n", __LINE__);\perror(msg);                   \
} while(0)#define PORT 6666
#define IP "127.0.0.1"int main(int argc,const char * argv[])
{//创建流式套接字int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd < 0){ERR_MSG("socket");return -1;}printf("socket create success\n");//填充地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);//连接到服务器if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0){ERR_MSG("connect");return -1;}printf("connect server success\n");char buf[128] = "";ssize_t res = 0;while(1){//发送数据bzero(buf, sizeof(buf));printf("请输入>>> ");fgets(buf, sizeof(buf), stdin);buf[strlen(buf)-1] = 0;if(send(cfd, buf, sizeof(buf), 0) < 0){ERR_MSG("send");return -1;}printf("发送成功\n");//接收数据bzero(buf, sizeof(buf));res = recv(cfd, buf, sizeof(buf), 0);if(res < 0){ERR_MSG("recv");return -1;}else if(0 == res){printf("[%s:%d] 服务器下线\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));break;}printf("[%s:%d]: %s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), buf); }close(cfd);return 0;
}

运行结果

 

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

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

相关文章

G-channel 实现低光图像增强

G-channel 之前研究低光图像增强时&#xff0c;看到一篇博客&#xff0c;里面介绍了一种方法&#xff0c;没有说明出处&#xff0c;也没有说明方法的名字&#xff0c;这里暂时叫做 G-channel 算法。 博客地址&#xff1a;低照度图像增强&#xff08;附步骤及源码&#xff09;…

LBP特征笔记

LBP&#xff0c;局部二值模式&#xff08;Local Binary Pattern&#xff09;&#xff0c;是一种描述图像局部纹理特征的方式&#xff0c;具有旋转不变性和灰度不变性。首先由T. Ojala, M.Pietikinen, 和 D. Harwood 在1994年提出。 LBP特征描述 基础LBP算子 基础的LBP算子定义…

# 关于Linux下的parted分区工具显示起始点为1049kB的问题解释

关于Linux下的parted分区工具显示起始点为1049kB的问题解释 文章目录 关于Linux下的parted分区工具显示起始点为1049kB的问题解释1 问题展示&#xff1a;2 原因3 修改为KiB方式显示4 最后 1 问题展示&#xff1a; kevinTM1701-b38cbc23:~$ sudo parted /dev/nvme1n1 GNU Part…

记一次使用gophish开展的钓鱼演练

这周接到客户要求&#xff0c;组织一次钓鱼演练&#xff0c;要求是发送钓鱼邮件钓取用户账号及个人信息。用户提交后&#xff0c;跳转至警告界面&#xff0c;以此来提高客户单位针对钓鱼邮件的防范意识。 与客户沟通后得知他们企业内部是由邮箱网关的&#xff0c;那么就意味着…

ARM微架构

一、流水线 二、指令流水线 指令流水线 指令流水线 指令流水线 ARM指令流水线 ARM7采用3级流水线 ARM9采用5级流水线 Cortex-A9采用8级流水线 注1&#xff1a;虽然流水线级数越来越多&#xff0c;但都是在三级流水线的基础上进行了细分 PC的作用&#xff08;取指&#xff09; …

搭建Django+pyhon+vue自动化测试平台

Django安装 使用管理员身份运行pycharm使用local 1 pip install django -i https://pypi.tuna.tsinghua.edu.cn/simple 检查django是否安装成功 1 python -m django --version 创建项目 1 1 django-admin startproject test cd 切换至创建的项目中启动django项目…

python 连接oracle pandas以简化excel的编写和数据操作

python代码 Author: liukai 2810248865qq.com Date: 2022-08-18 04:28:52 LastEditors: liukai 2810248865qq.com LastEditTime: 2023-07-06 22:12:56 FilePath: \PythonProject02\pandas以简化excel的编写和数据操作.py Description: 这是默认设置,请设置customMade, 打开koro…

SpringBoot+AOP+Redission实战分布式锁

文章目录 前言一、Redission是什么&#xff1f;二、使用场景三、代码实战1.项目结构2.类图3.maven依赖4.yml5.config6.annotation7.aop8.model9.service 四、单元测试总结 前言 在集群环境下非单体应用存在的问题&#xff1a;JVM锁只能控制本地资源的访问&#xff0c;无法控制…

docker容器的基本操作

一、查看Docker的版本信息 [roothuyang1 ~]# docker version 二、查看docker的详细信息 [roothuyang1 ~]# docker info 三、Docker镜像操作 Docker创建容器前需要本地存在对应的镜像&#xff0c;如果本地加载不到相关镜像&#xff0c;Docker默认就会尝试从镜像仓库https://hu…

算法竞赛入门【码蹄集新手村600题】(MT1100-1120)C语言

算法竞赛入门【码蹄集新手村600题】(MT1100-1120&#xff09;C语言 目录MT1101 带参数的宏IIMT1102 长方体MT1103 球体积MT1104 三角形MT1105 英寸英尺英里MT1106 盎司磅MT1107 加仑/升MT1108 保留小数MT1109 和10相比MT1110 最小值MT1111 最大值MT1112 中庸之道MT1113 三人同行…

代码随想录算法训练营第17期第28天 | 93.复原IP地址 、78.子集 、​ 90.子集II

93. 复原 IP 地址 1.当点号有三个之后&#xff0c;当最后一部分数值是有效的话&#xff0c; 就可以加入结果集了 class Solution { public:vector<string> res;bool isvalid(const string& s, int left, int right){if (right < left){return false;}if (s[left]…

-bash: fork: retry: Resource temporarily unavailable 问题解决

错误提示&#xff1a; -bash: fork: retry: Resource temporarily unavailable 错误分析&#xff1a;之前已经出现过这种资源限制的报错提醒&#xff0c;然后整个系统可用的连接数就已经用完了&#xff0c;无法使用工具来获取系统信息&#xff0c;所以将运行的任务脚本kill后开…

【运维工程师学习八】代理及安装配置Nginx反向代理

【运维工程师学习八】代理 正向代理一、使用正向代理的主要作用有&#xff1a;二、反向代理三、使用反向代理的主要作用有&#xff1a;四、透明代理五、各种代理的主要区别六、Nginx的安装七、了解nginx的文件位置八、了解nginx程序的命令行参数九、开启nginx反向代理十、解读n…

less的使用

less的介绍&#xff1a; less使用 1、 less使用的第一种用法&#xff0c;起变量名&#xff0c;变量名区分大小写&#xff1a; 这里我们定义一个粉色变量 我想使用直接把变量拿过来就行 2、vscode使用插件&#xff0c;直接将Css文件转换less文件&#xff1a; 3、第二种用法&…

【力扣每日一题】2023.8.5 合并两个有序链表

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们两个有序的链表&#xff0c;要我们保持升序的状态合并它们。 我们可以马上想要把两个链表都遍历一遍&#xff0c;把所有节点的…

android Android Studio Giraffe | 2022.3.1 版本Lombok不兼容 解决方案

android Android Studio Giraffe | 2022.3.1 版本Lombok不兼容 解决方案 1.查看当前的android studio 版本 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 2.打开 idea 官网下载页面 idea下载历史版本 找到对应的版本编号…

MySQL 与MongoDB区别

一、什么是MongoDB呢 ? MongoDB 是由C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。在高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB 将数据存储为一…

集中/本地转发、AC、AP

1.ADSL ADSL MODEM&#xff08;ADSL 强制解调器&#xff09;俗称ADSL猫 ADSL是一种异步传输模式&#xff08;ATM)。ADSL是指使用电话线上网&#xff0c;需要专用的猫&#xff08;Modem)&#xff0c;在上网的时候高频和低频分离&#xff0c;所以上网电话两不耽误&#xff0c;速…

Vue命名规范

JS文件命名 一般采用的是小驼峰命名法&#xff0c;如 pieChartHelp 第一个单词小写&#xff0c;其他单词首字母大写 Components 文件命名 一般采用的是大驼峰命名法&#xff0c;如PieChart 所有单词的首字母大写 常量命名 一般全部大写&#xff0c;每个单词使用分隔符隔开&…

若依打印sql

官方issue 自动生成的代码&#xff0c;sql日志怎么没有打印 在ruoyi-admin中的application.yml配置如下。 # 日志配置&#xff0c;默认 logging:level:com.ruoyi: debugorg.springframework: warn#添加配置com.ying: debug输出sql