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


相关文章
|
19天前
|
Java Linux
Springboot 解决linux服务器下获取不到项目Resources下资源
Springboot 解决linux服务器下获取不到项目Resources下资源
|
22天前
|
Linux
linux下搭建tftp服务器教程
在Linux中搭建TFTP服务器,需安装`tftp-server`(如`tftpd-hpa`)。步骤包括:更新软件包列表,安装`tftpd-hpa`,启动并设置开机自启,配置服务器(编辑`/etc/default/tftpd-hpa`),添加选项,然后重启服务。完成后,可用`tftp`命令进行文件传输。例如,从IP`192.168.1.100`下载`file.txt`: ``` tftp 192.168.1.100 &lt;&lt;EOF binary put file.txt quit EOF ```
30 4
|
2天前
|
监控 Linux 网络安全
Linux服务器如何查询连接服务器的IP
【4月更文挑战第17天】Linux服务器如何查询连接服务器的IP
7 1
|
2天前
|
Linux
如何将一个linux服务器挂载到另外一个linux服务器上
如何将一个linux服务器挂载到另外一个linux服务器上
13 1
|
4天前
|
监控 安全 Linux
Linux系统之安装ServerBee服务器监控工具
【4月更文挑战第22天】Linux系统之安装ServerBee服务器监控工具
43 2
|
8天前
|
网络协议 安全 Linux
IDEA通过内网穿透实现固定公网地址远程SSH连接本地Linux服务器
IDEA通过内网穿透实现固定公网地址远程SSH连接本地Linux服务器
|
13天前
|
数据采集 API 数据安全/隐私保护
畅游网络:构建C++网络爬虫的指南
本文介绍如何使用C++和cpprestsdk库构建高效网络爬虫,以抓取知乎热点信息。通过亿牛云爬虫代理服务解决IP限制问题,利用多线程提升数据采集速度。示例代码展示如何配置代理、发送HTTP请求及处理响应,实现多线程抓取。注意替换有效代理服务器参数,并处理异常。
畅游网络:构建C++网络爬虫的指南
|
15天前
|
Linux 数据安全/隐私保护
Linux基础与服务器架构综合小实践
【4月更文挑战第9天】Linux基础与服务器架构综合小实践
1246 8
|
存储 弹性计算 自然语言处理
使用阿里云ECS的开发心得
关于本人使用阿里云ECS的开发心得与使用经验。分享开发提高效率的方法、使用心得。
使用阿里云ECS的开发心得
|
23天前
|
弹性计算
阿里云ECS使用体验
在申请高校学生免费体验阿里云ECS云服务器后的一些使用体验和感受。