Linux C/C++ 开发(学习笔记十二 ):TCP服务器(并发网络编程io多路复用epoll)

简介: Linux C/C++ 开发(学习笔记十二 ):TCP服务器(并发网络编程io多路复用epoll)

一、了解epoll

可以通过epoll实现io多路复用

深入了解epoll

epoll使用详解

二、完整代码

epoll水平触发(LT)和边沿触发(ET)概念较为重要

开发过程中,一定要注意sockfd要在epoll这个集合里面

使用epoll肯定会有一个 事件的主循环。

#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/epoll.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define BUFFER_LENGTH 1024
#define EPOLL_SIZE 1024
int main(int argc,char** argv){
    if(argc<2){
        printf("Param Error\n");
        return -1;
    }
    int port=atoi(argv[1]);
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in addr;
    memset(&addr,0,sizeof(sockaddr_in));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr.s_addr=INADDR_ANY;
    if(bind(sockfd,(sockaddr*)&addr,sizeof(sockaddr_in))<0){
        perror("bind");
        return 2;
    }
    if(listen(sockfd,5)<0){
        perror("listen");
        return 3;
    }
    int epfd=epoll_create(1);//里面的参数只要大于0就ok,里面的参数只有0和1的区别
    epoll_event events[EPOLL_SIZE]={0};
    epoll_event ev;
    ev.events=EPOLLIN;//EPOLLIN表示有数据来了
    ev.data.fd=sockfd;
    epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ev);//将 监听的sockfd(门卫)交给epollfd(快递员)管理
    while(1){
        int nready=epoll_wait(epfd,events,EPOLL_SIZE,0);//返回值为事件个数 ;第四个参数:-1表示永久阻塞,0表示立即返回,如果是n,那么n个时间间隔执行一次。
        if(nready==-1) continue;//如果一个事件都没有就continue
        for(int i=0;i<nready;i++){//nready中包含了listenfd和clientfd,这两个要区别处理
           if(events[i].data.fd==sockfd){//listenfd  //有新的客户端连接
                sockaddr_in client_addr;
                memset(&client_addr,0,sizeof(sockaddr_in));
                socklen_t client_len=sizeof(client_addr);
                int clientfd=accept(sockfd,(sockaddr*)&client_addr,&client_len);
                ev.events=EPOLLIN|EPOLLET;//边沿触发
                ev.data.fd=clientfd;
                epoll_ctl(epfd,EPOLL_CTL_ADD,clientfd,&ev);//把新的的客户fd加入到epoll中
            }else{
                int clientfd=events[i].data.fd;
                char buffer[BUFFER_LENGTH]={0};
                int len=recv(clientfd,buffer,BUFFER_LENGTH,0);
                if(len<0){
                    close(clientfd);
                    ev.events=EPOLLIN;
                    ev.data.fd=clientfd;
                    epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,&ev);
                    break;
                }
                else if(len==0){
                    close(clientfd);
                    ev.events=EPOLLIN;
                    ev.data.fd=clientfd;
                    epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,&ev);
                    break;
                }
                else{
                    printf("Recv:%s,%d bytes\n",buffer,len);
                }
            }
        }
    }
    return 0;
}

三、补充:

1.在建立连接的时候

比如建立3个客户端连接(假设没有其他输入)

每次循环,nready都为1,表示listenfd接收到要连接的客户端。while(1)这个大循环,循环3次,加入3个客户端fd。

2.断开连接也会接受到信息

断开的时候clientfd会发出信息,也就是events[i].data.fd!=sockfd的情况,此时len==0,进行客户端断开

3.多个客户端同时发送消息时

比如有5个客户端同时发送信息(假设没有新得客户端连接)

那么此时的nready=5

4.水平触发(LT)和边沿触发(ET)

LT模式下,只要存在未读完的数据,就会进行重复读取。

ET模式下,只在数据发生变化时,才会进行一次读取,如果数据过长,可能有部分数据没有读取的风险。但是效率比水平触发高

5.EPOLLIN代表读取数据

如果没有设置读取数据,那么接受数据的时候,就没法得到对应的数据,如果都设置0,那么nready=0


相关文章
|
4月前
|
存储 弹性计算 网络协议
阿里云服务器ECS实例规格族是什么?不同规格CPU型号、处理器主频及网络性能参数均不同
阿里云ECS实例规格族是指具有不同性能特点和适用场景的实例类型集合。不同规格族如计算型c9i、通用算力型u1、经济型e等,在CPU型号、主频、网络性能、云盘IOPS等方面存在差异。即使CPU和内存配置相同,性能参数和价格也各不相同,适用于不同业务需求。
439 144
|
5月前
|
JSON 监控 API
在线网络PING接口检测服务器连通状态免费API教程
接口盒子提供免费PING检测API,可测试域名或IP的连通性与响应速度,支持指定地域节点,适用于服务器运维和网络监控。
592 0
|
5月前
|
机器学习/深度学习 存储 监控
内部文件审计:企业文件服务器审计对网络安全提升有哪些帮助?
企业文件服务器审计是保障信息安全、确保合规的关键措施。DataSecurity Plus 是由卓豪ManageEngine推出的审计工具,提供全面的文件访问监控、实时异常告警、用户行为分析及合规报告生成功能,助力企业防范数据泄露风险,满足GDPR、等保等多项合规要求,为企业的稳健发展保驾护航。
168 0
|
6月前
|
存储 运维 API
HPE OneView 10.0 - HPE 服务器、存储和网络设备集中管理软件
HPE OneView 10.0 - HPE 服务器、存储和网络设备集中管理软件
148 1
|
4月前
|
存储 监控 Linux
Dell OpenManage Enterprise 4.5 - Dell 服务器、存储和网络设备集中管理软件
Dell OpenManage Enterprise 4.5 - Dell 服务器、存储和网络设备集中管理软件
132 0
|
6月前
|
C# 图形学 开发者
Unity开发中使用UnityWebRequest从HTTP服务器下载资源。
总之,UnityWebRequest就是游戏开发者手中的万能钓鱼竿,既可以获取文本数据,也能钓上图片资源,甚至是那声音的涟漪。使用UnityWebRequest的时候,你需要精心准备,比如确定URL、配置请求类型和头信息;发起请求;巧妙处理钓获的数据;还需要机智面对网络波澜,处理各种可能出现的错误。按照这样的过程,数据的钓取将会是一次既轻松愉快也效率高效的编程钓鱼之旅。
328 18
|
7月前
|
监控 应用服务中间件 Linux
掌握并发模型:深度揭露网络IO复用并发模型的原理。
总结,网络 I/O 复用并发模型通过实现非阻塞 I/O、引入 I/O 复用技术如 select、poll 和 epoll,以及采用 Reactor 模式等技巧,为多任务并发提供了有效的解决方案。这样的模型有效提高了系统资源利用率,以及保证了并发任务的高效执行。在现实中,这种模型在许多网络应用程序和分布式系统中都取得了很好的应用成果。
241 35
|
7月前
|
存储 安全 Linux
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
264 4
Dell OpenManage Enterprise 4.4 - Dell 服务器、存储和网络设备集中管理软件
|
7月前
|
存储 消息中间件 弹性计算
阿里云服务器ECS计算型c7和通用算力型u1在适用场景、计算性能、网络与存储性能等方面的对比
阿里云ECS服务器u1和c7实例在适用场景、性能、处理器特性等方面存在显著差异。u1为通用算力型,性价比高,适合中小企业及对性能要求不高的场景;c7为企业级计算型,采用最新Intel处理器,性能稳定且强大,适用于高性能计算需求。u1支持多种CPU内存配比,但性能一致性可能受底层平台影响;c7固定调度模式,确保高性能与稳定性。选择时可根据预算与性能需求决定。
401 23