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;
}
相关推荐
feng_you_ying_li17 分钟前
linux之用户的权限详解(4)
linux·运维·服务器
二进制person1 小时前
JavaEE初阶 --网络编程
linux·服务器·网络
Irissgwe2 小时前
进程间通信
linux·服务器·网络·c++·进程间通信
岁岁种桃花儿3 小时前
AI超级智能开发系列从入门到上天第四篇:AI应用方案设计
java·服务器·开发语言
TEC_INO4 小时前
嵌入式 Linux 开发知识总结
linux·运维·服务器
养生技术人4 小时前
Oracle OCP认证考试题目详解082系列第5题
运维·数据库·sql·oracle·开闭原则
原来是猿4 小时前
VS Code Remote-SSH 连接失败:提示过程试图写入的管道不存在
linux·服务器·ssh
坚持就完事了5 小时前
Linux中的权限信息
linux·运维·服务器
殷紫川5 小时前
告别手动部署噩梦:CI/CD 持续交付全链路实战
运维·架构·自动化运维
顶点多余5 小时前
进程间通信 --- 共享内存篇(通信速度最快)
linux·服务器·jvm