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;
}
相关推荐
梁萌2 小时前
Linux安装mysql8.4.6
linux·运维·mysql安装·8.4.6
南棱笑笑生2 小时前
20251028在Ubuntu20.04.6上编译AIO-3576Q38开发板的Buildroot系统
大数据·linux·服务器·rockchip
FreeBuf_2 小时前
Ubuntu内核曝严重UAF漏洞,可致攻击者获取Root权限
linux·运维·ubuntu
☆璇2 小时前
【Linux】数据链路层
linux·服务器·网络
初学者_xuan3 小时前
零基础新手小白快速了解掌握服务集群与自动化运维(十六)集群部署模块——Keepalived双机热备
运维·自动化·github
行思理3 小时前
Dockerfile 各指令说明
运维·macos·docker·容器·php
阿巴~阿巴~4 小时前
线程局部存储(Thread-Local Storage, TLS)
linux·服务器·开发语言·c++·线程·虚拟地址空间·线程局部存储
半梦半醒*4 小时前
k8s——资源管理
linux·运维·docker·容器·kubernetes·自动化
gfdgd xi5 小时前
GXDE For deepin 25:deepin25 能用上 GXDE 了!
linux·运维·python·ubuntu·架构·bug·deepin
落世繁华5 小时前
Docker快速部署--Mysql一键初始化
运维·mysql·docker·容器·一键部署