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;
}
相关推荐
阿里云大数据AI技术3 小时前
阿里云 EMR AI 助手正式发布:从问答工具到全栈智能运维助手
运维·人工智能
你好潘先生9 小时前
别再记命令了,用 yeero do 说句人话就能跑脚本,而且不烧 token
服务器·python·命令行
SkyWalking中文站1 天前
认识 Horizon UI · 6/17:Trace 探索器
运维·监控·自动化运维
程序员老赵1 天前
服务器文件不想 SFTP 上传?Docker 跑个 File Browser,浏览器就能管理
服务器·docker·开源
火车叼位1 天前
写给初级开发者:SSL、SSH、HTTPS 与证书体系全解析
运维
vivo互联网技术1 天前
从 10 分钟到 1 秒:ES 深度分页任意跳页的三轮优化实战
服务器·数据库·redis·elasticsearch·深度分页
小猿姐2 天前
唯品会大规模数据库云原生实践:基于 KubeBlocks 管理数千实例的统一运维之路
运维·elasticsearch·云原生
SkyWalking中文站2 天前
认识 Horizon UI · 5/17:3D 基础设施地图
运维·监控·自动化运维
SkyWalking中文站3 天前
认识 Horizon UI · 1/17:SkyWalking 新一代可观测性控制台
运维·前端·监控