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


相关文章
|
12月前
|
安全 Linux 网络安全
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
315 0
Nipper 3.9.0 for Windows & Linux - 网络设备漏洞评估
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
480 19
|
Linux 数据安全/隐私保护
使用Linux命令行接入无线网络Wi-Fi的示例。
现在,你已经使用命令行成功地连接到 Wi-Fi 网络了。这两个示例涵盖了用 `nmcli` 和 `wpa_supplicant` 连接无线网络的常见场景,让你能够不依赖图形化界面来完成这个任务。在日常使用中熟练掌握这些基本操作能增强你对 Linux 系统的理解,帮助你更有效地处理各种问题。
1255 12
|
Ubuntu Linux
Linux系统管理:服务器时间与网络时间同步技巧。
以上就是在Linux服务器上设置时间同步的方式。然而,要正确运用这些知识,需要理解其背后的工作原理:服务器根据网络中的其他机器的时间进行校对,逐步地精确自己的系统时间,就像一只犹豫不决的啮齿动物,通过观察其他啮齿动物的行为,逐渐确定自己的行为逻辑,既简单,又有趣。最后希望这个过程既能给你带来乐趣,也能提高你作为系统管理员的专业素养。
2497 20
|
安全 Ubuntu Linux
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
735 0
Nipper 3.8.0 for Windows & Linux - 网络设备漏洞评估
|
JSON 运维 Ubuntu
Linux下如何使用Curl进行网络请求
希望这篇文章能帮助您在Linux下更好地使用Curl进行网络请求。如有疑问,请随时提问!
1049 10
|
网络协议 Unix Linux
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
991 11
|
11月前
|
弹性计算 运维 安全
阿里云轻量应用服务器与云服务器ECS啥区别?新手帮助教程
阿里云轻量应用服务器适合个人开发者搭建博客、测试环境等低流量场景,操作简单、成本低;ECS适用于企业级高负载业务,功能强大、灵活可扩展。二者在性能、网络、镜像及运维管理上差异显著,用户应根据实际需求选择。
910 10
|
11月前
|
弹性计算 ice
阿里云4核8g服务器多少钱一年?1个月和1小时价格,省钱购买方法分享
阿里云4核8G服务器价格因实例类型而异,经济型e实例约159元/月,计算型c9i约371元/月,按小时计费最低0.45元。实际购买享折扣,1年最高可省至1578元,附主流ECS实例及CPU型号参考。
926 8
|
11月前
|
运维 安全 Ubuntu
阿里云渠道商:服务器操作系统怎么选?
阿里云提供丰富操作系统镜像,涵盖Windows与主流Linux发行版。选型需综合技术兼容性、运维成本、安全稳定等因素。推荐Alibaba Cloud Linux、Ubuntu等用于Web与容器场景,Windows Server支撑.NET应用。建议优先选用LTS版本并进行测试验证,通过标准化镜像管理提升部署效率与一致性。