epoll多路复用io实现并发服务器

main.c

c 复制代码
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/epoll.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include <arpa/inet.h>
/* According to earlier standards */
#include <sys/time.h>
#define SERVER_PORT 8800
#define SERVER_IP "192.168.250.100"

int main(int argc, char const *argv[])
{
     struct epoll_event event;
     struct epoll_event events[10];//存放就绪事件描述符的数组
    char buf[128]={0};
    int epfd; 
    int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0){
		printf("socket error \n");
		return -1;
	}
  
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		printf("setsockopt error\n");
		return -1;
	}
	struct sockaddr_in sina;
	sina.sin_family = AF_INET;
	sina.sin_port  =htons(SERVER_PORT);
	sina.sin_addr.s_addr = inet_addr(SERVER_IP);
	if(bind(sfd,(struct sockaddr*)&sina,sizeof(sina))<0)
	{
		printf("bind error\n");
		return -1;
	}
    
    if(listen(sfd, 128) < 0)
    {
        printf("listen error\n");
        return -1;
    }
     
    epfd = epoll_create(1);
    if(epfd<0)
    {
        printf("epoll_create filed\n");
        exit(-1);
    }
    
    //添加准备就绪事件进入epoll;
    event.events=EPOLLIN;//读事件
    event.data.fd=sfd;
    if(epoll_ctl(epfd,EPOLL_CTL_ADD,sfd,&event)<0)
    {
        printf("epoll_ctl add filed\n");
    }
    
    int s_res = 0;
    struct sockaddr_in cin;     //存储客户端信息
    socklen_t len = sizeof(cin);
    int newfd = -1;
    ssize_t res = 0;
    while (1)
    {
        //如果成功,ret接收返回的事件个数,把就绪的事件放在events数组中
        int ret=epoll_wait(epfd,events,10,-1);

        if(ret<0)
        {
            printf("epoll_wait filed\n");
            exit(-1);
        }

        int i;
        //循环遍历数组,做事件的处理
        for(i=0;i<ret;i++)
        {
            if(events[i].events&EPOLLIN)
            {
                if(events[i].data.fd==sfd){                
                //添加准备就绪事件进入epoll;
                event.events=EPOLLIN;//读事件
                newfd = accept(sfd, (struct sockaddr*)&cin, &len);
                event.data.fd=newfd;
                if(epoll_ctl(epfd,EPOLL_CTL_ADD,newfd,&event)<0)
                {
                    printf("epoll_ctl add filed\n");
                }
                }else{
                   res = read(events[i].data.fd,buf,sizeof(buf));
                    printf("buf:%s\n",buf);
                    if(res == 0){                        
                      if(epoll_ctl(epfd,EPOLL_CTL_DEL,events[i].data.fd,&event)<0)
                        {
                            printf("epoll_ctl del filed\n");
                        } 
                        close(events[i].data.fd); 
                    }
                }
            }
        }
    }
    close(sfd);



    return 0;
}
相关推荐
数字新视界10 小时前
空调控制器AIRC800的智能化管理与应用实践
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
知已难寻10 小时前
01 · OpenStack的认证管理 Keystone
运维·服务器·云原生·云计算·openstack
ai_xiaogui11 小时前
私有化部署大模型实战:PanelAI 一键搭建、Token 计费与多用户隔离
运维·私有化部署·大模型部署·大模型 token 计费·api key 统一管理·多用户实例隔离·应用市场一键部署
企鹅侠客11 小时前
Linux CPU 负载平均值(Load Average)详解:从原理到实践
linux·运维·服务器·服务器负载
易点云徐源11 小时前
HP 暗影精灵 PRO 16 安装双系统后,开机直接进入 Windows,按 F9 才能进入 Ubuntu:GRUB 菜单不显示的处理方法
linux·运维·ubuntu
吃一碗粉只付一碗钱11 小时前
10-令牌里的用户主键不要明文
服务器·数据库·sql·sqlserver·c#
木雷坞11 小时前
Baserow Docker部署:导入设备借用CSV,再用表单新增登记
运维·docker·容器
Linux运维技术栈12 小时前
WAF部署在防火墙后面,获取不到真实IP怎么办?
服务器·网络·tcp/ip·安全·防火墙·waf
程序员大雄学编程12 小时前
crontab 脚本不写日志?我把 7 个原因在 Ubuntu 上逐个复现了一遍
运维
广目软件12 小时前
HA分布式架构采集节点变更操作手册20261029
运维·服务器·ansible·zabbix·prometheus