Linux-c TCP服务模型

1、TCP模型,服务端与客户端的搭建时序图

2、TCP模型,在创建阶段和通信阶段,对套接字的理解

2.1、tcp连接阶段

2.2、tcp通信状态

一个服务端与多个客户端的通信状态

TCP与UDP的对比

(下图是笔者理解所画,可能也许有错,欢迎指出)

3、基于EPOLL多路复用模型,代码实现的TCP服务端和客户端

3.1、EPOLL的几个主要的函数

3.1.1、epoll_create1(int flags)

创建epfd,笔者理解,这个是管理众多事件的一个集合。

3.1.2、epoll_ctl

用于添加和删除fd及其关联的事件

3.1.3、epoll_wait

阻塞等待监听的fd的时间发生变化

3.2、服务端代码(TCP+EPOLL)

#define BACKLOG 50  //支持多少个客户端连接int main(int argc, const char *argv[])
{//socketint server=socket(AF_INET, SOCK_STREAM, 0);if(server == -1){perror("socket error");return -1;}//bindstruct sockaddr_in serverAddr;serverAddr.sin_family=AF_INET;serverAddr.sin_port=htons(atoi(argv[1]));serverAddr.sin_addr.s_addr=inet_addr("0.0.0.0");if(bind(server,(struct sockaddr*)&serverAddr, sizeof(serverAddr))==-1){perror("bind server error");return -1;}//listenif(listen(server, BACKLOG)==-1){perror("listen error");return -1;}//epoll_createint epfd=epoll_create1(EPOLL_CLOEXEC);if(epfd==-1){perror("epoll_create1 error");return -1;}//epoll_ctl add/delstruct epoll_event e1;e1.data.fd=server;e1.events=EPOLLIN;if(epoll_ctl(epfd, EPOLL_CTL_ADD, server, &e1)==-1){//server文件FDperror("epoll_ctl add 1: error");return -1;}struct epoll_event e2;e2.data.fd=0;e2.events=EPOLLIN;if(epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &e2)==-1){//标准输入perror("epoll_ctl add 2:error");return -1;}while(1){//epoll_waitstruct epoll_event eArr[50];int num=epoll_wait(epfd, eArr,50,-1);//printf("num=[%d]\n", num);//if(num >= 2){//	printf("num=[%d]!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", num);//}if(num == -1){perror("epoll_wait error");return -1;}for(int i=0;i<num;i++){int fd=eArr[i].data.fd;int events=eArr[i].events;//以下由于只监听了EPOLLIN,因此不对事件进行判断if(fd==server){//服务端监听套接字struct sockaddr_in clientAddr;socklen_t clientAddrLen;int fd=accept(server, (struct sockaddr*)&clientAddr, &clientAddrLen);printf("有新的客户端连接[%s]:[%d],FD=[%d]\n",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port),fd);//将此客户端fd添加到epfd中struct epoll_event e3;e3.data.fd=fd;e3.events=EPOLLIN;if(epoll_ctl(epfd,EPOLL_CTL_ADD,fd, &e3)==-1){perror("epoll_ctl add 3 error");return -1;}continue;}if(fd==0){//标准输入流printf("请输入:");char buf[64];fgets(buf,sizeof(buf), stdin);buf[strlen(buf)-1]=0;printf("键盘键入了:%s\n", buf);continue;}//客户端char buf[64]={0};struct sockaddr_in clientAddr;socklen_t clientAddrLen;ssize_t cnt=recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&clientAddr, &clientAddrLen);printf("<<收到来自[%s]:[%d]的消息:\n[%ld]:%s\n",inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port),cnt,buf);if(cnt == 0){printf("<<客户端[%s]:[%d]的断开了连接:\n",inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));//从epfd中删除这个fdepoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);continue;}//TODO 转换成大写,返还给客户端for(int j=0;j<cnt;j++){buf[j]=toupper(buf[j]);}cnt=send(fd, buf, sizeof(buf), 0);printf(">>向[%s]:[%d]发送了消息:\n[%ld]:%s\n",inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port),cnt,buf);}}return 0;
}

3.3、客户端代码(TCP+EPOLL)

int main(int argc, const char *argv[])
{//tcp epoll客户端//socketint client=socket(AF_INET, SOCK_STREAM, 0);if(client == -1){perror("socket error");return -1;}//connectstruct sockaddr_in serverAddr;serverAddr.sin_family=AF_INET;serverAddr.sin_port=htons(atoi(argv[1]));serverAddr.sin_addr.s_addr=inet_addr("127.0.0.1");if(connect(client, (struct sockaddr*)&serverAddr,sizeof(serverAddr))==-1){perror("connect error");return -1;}printf("与服务端成功创建连接\n");//epoll createint epfd=epoll_create1(EPOLL_CLOEXEC);if(epfd == -1){perror("epoll_create1 error");return -1;}//epoll ctl addstruct epoll_event e1;e1.data.fd=client;//将客户端fd,收到消息事件,添加e1.events=EPOLLIN;if(epoll_ctl(epfd, EPOLL_CTL_ADD, client, &e1)==-1){perror("epoll_ctl error [1]");return -1;}//添加事件:键盘输入//struct epoll_event e1;e1.data.fd=0;//将客户端fd,收到消息事件,添加e1.events=EPOLLIN;if(epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &e1)==-1){perror("epoll_ctl error [1]");return -1;}while(1){struct epoll_event eArr[2];int num=epoll_wait(epfd, eArr, 2, -1);if(num == -1){perror("epoll_wait error");return -1;}for(int i=0;i<num;i++){int fd=eArr[i].data.fd;int es=eArr[i].events;printf("fd=[%d],es=[%d]\n", fd, es);if(fd == 0){//键盘输入char buf[64]={0};fgets(buf, sizeof(buf), stdin);buf[strlen(buf)-1]=0;printf("键盘输入了:%s\n", buf);ssize_t cnt=send(client, buf,strlen(buf),0);printf("发送了[%ld]:%s\n", cnt, buf);if(cnt == -1){perror("send error");}continue;}if(fd == client){//收到消息char buf[64]={0};ssize_t cnt=recv(fd, buf, sizeof(buf), 0);printf("收到[%ld]:%s\n", cnt, buf);continue;}//不知道fprintf(stderr, "错误的监听FD[%d]\n", fd);}}//epoll ctl del//epoll waitreturn 0;
}

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

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

相关文章

卡码网KamaCoder 127. 骑士的攻击

题目来源&#xff1a;127. 骑士的攻击 C题解&#xff08;来源A * 算法精讲 &#xff08;A star算法&#xff09; | 代码随想录&#xff09;&#xff1a;Astar Astar 是一种 广搜的改良版。 有的是 Astar是 dijkstra 的改良版。 其实只是场景不同而已 我们在搜索最短路的时候&…

浅谈语言模型推理框架 vLLM 0.6.0性能优化

在此前的大模型技术实践中&#xff0c;我们介绍了加速并行框架Accelerate、DeepSpeed及Megatron-LM。得益于这些框架的助力&#xff0c;大模型的分布式训练得以化繁为简。 然而&#xff0c;企业又该如何将训练完成的模型实际应用部署&#xff0c;持续优化服务吞吐性能&#xf…

软著补正有哪些类型

软著补正是指在软著申请过程中&#xff0c;版权局在审核软著申请材料时&#xff0c;发现一些部分不符合规定的内容&#xff0c;从而对申请材料提出补正要求&#xff0c;要求申请人修改或补充申请材料。软著补正通常涉及以下几种类型&#xff1a; 一、申请材料填写有误 软件名称…

闯关leetcode——3222. Find the Winning Player in Coin Game

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/find-the-winning-player-in-coin-game/description/ 内容 You are given two positive integers x and y, denoting the number of coins with values 75 and 10 respectively. Alice and Bob a…

GitLab 中文发行版最新版重点功能解读

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…

大数据数据存储层MemSQL, HBase与HDFS

以下是对 MemSQL、HBase 和 HDFS 的详细介绍,这些工具在分布式数据存储和处理领域有着重要作用。 1. MemSQL MemSQL(现称为 SingleStore)是一种分布式内存数据库,兼具事务处理(OLTP)和分析处理(OLAP)的能力,专为高性能实时数据处理设计。 1.1 核心特点 内存优先存储…

斗破QT编程入门系列之二:GUI应用程序设计基础:UI文件(四星斗师)

斗破Qt目录&#xff1a; 斗破Qt编程入门系列之前言&#xff1a;认识Qt&#xff1a;Qt的获取与安装&#xff08;四星斗师&#xff09; 斗破QT编程入门系列之一&#xff1a;认识Qt&#xff1a;初步使用&#xff08;四星斗师&#xff09; 斗破QT编程入门系列之二&#xff1a;认识…

《二分查找算法:在有序数组中搜索目标值》

目录 一、问题分析 二、二分查找算法原理 三、代码实现 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target&#xff0c;我们要写一个函数来搜索 nums 中的 target&#xff0c;如果目标值存在就返回它的下标&#xff0c;否则返回 -1。 …

【Qt】QTreeView 和 QStandardItemModel的关系

QTreeView 和 QAbstractItemModel&#xff08;通常是其子类&#xff0c;如 QStandardItemModel 或自定义模型&#xff09;是 Qt 框架中的两个关键组件&#xff0c;它们之间存在密切的关系。 关系概述 QTreeView&#xff1a; QTreeView 是一个用于显示和编辑层次数据的视图小部…

高级 HarmonyOS主题课—— 帮助快速构建各种文本识别应用的课后习题

天地不仁&#xff0c;以万物为刍狗&#xff1b; 圣人不仁&#xff0c;以百姓为刍狗。 天地之间&#xff0c;其犹橐龠乎&#xff1f; 虚而不屈&#xff0c;动而俞出。 多闻数穷&#xff0c;不若守于中。 本文内容主要来自 <HarmonyOS主题课>帮助快速构建各种文本识别应用 …

达梦数据库DM管理工具增删改不生效怎么办?如何设置事务自动提交?

前言 我在使用达梦数据库DM时&#xff0c;一开始使用的是达梦数据库自带的连接工具DM管理工具。自带的有它自己的好处&#xff0c;起码对于修改新增字段等是比较兼容的。后面我发现DBeaver也是支持连接达梦数据库的&#xff0c;所以后面用DBeaver也在连接达梦数据库。 我在一…

力扣排序455题(分发饼干)

假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。 但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i],这是能 让孩子们满足胃口的饼干的最小尺寸;并且每块饼 干j&#xff0c;都有一个尺寸 s[j]。如果 s[j]> g[i]&…

Hadoop---MapReduce(3)

MapTask工作机制 &#xff08;1&#xff09;Read阶段&#xff1a;MapTask通过InputFormat获得的RecordReader&#xff0c;从输入InputSplit中解析出一个个key/value。 &#xff08;2&#xff09;Map阶段&#xff1a;该节点主要是将解析出的key/value交给用户编写map()函数处理&…

ssm052游戏攻略网站的设计与实现+vue(论文+源码)-kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;游戏攻略网站设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本游戏攻略网站就是在这…

Python中的extend()方法与+操作符和list.append()方法的异同

在Python编程中&#xff0c;我们经常需要将一个列表的元素添加到另一个列表中。有几种方法可以实现这一点&#xff0c;包括extend()方法、操作符和list.append()方法。本文将详细讨论这三种方法的异同&#xff0c;帮助你更好地理解它们在实际编程中的应用。 1. extend()方法 e…

Word大珩助手:超大数字怎么读?35位数字?69位数字?

俄罗斯日前对谷歌开出了20000000000000000000000000000000000&#xff08;35位数字&#xff09;美元的罚款 这一数字远超全球GDP总和&#xff0c;消息一出很快就登上热搜。 面对这样一个庞大的数字&#xff0c;人们不禁好奇&#xff0c;这样的数字该如何读出来&#xff1f; …

VisionPro —— CogIPOneImgeTool工具详解

CogIPOneImageTool工具主要用来对单张图像进行算法处理操作 CogIPOneImgeTool简介 CogIPOneImageTool 工具可完成高斯平滑、高通滤波和图像量化等基本图像处理操作。Image Processing One Image 工具编辑控件为此工具提供图形用户界面。 Image Processing Operations (图像处…

sql数据库-DQL-条件查询

条件查询 SELECT 字段列表 FROM 表名 WHERE 条件列表; 条件列表 比较运算符功能> 大于>大于等于 < 小于<小于等于等于!不等于between...and...某个范围之间&#xff08;闭区间&#xff09;IN(...)在in之后的列表中的值&#xff0c;多选一LIKE 通…

更快更强 | HP15加热台新品!Max温度350度,200度只需60秒!30~150W功率可调,恒温加热和回流焊双模式!

正点原子HP15加热台更快更强&#xff01;最高温度可达350度&#xff0c;200度只需60秒&#xff01;30~150W功率可调&#xff0c;恒温加热和回流焊双模式&#xff01; HP15是正点原子全新推出的迷你恒温加热台&#xff0c;设备支持30~150W功率可调&#xff0c;在150W功率下从室温…

WebRTC 环境搭建

主题 本文主要描述webrtc开发过程中所需的环境搭建 环境&#xff1a; 运行环境&#xff1a;ubuntu 20.04 Node.js环境搭建 安装编译 Node.js 所需的依赖包: sudo apt-get update sudo apt-get install -y build-essential libssl-dev 下载 Node.js 源码: curl -sL htt…