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 分钟前
【客户端方案】Electron / 原生客户端在内网会议中的取舍与坑点
服务器·electron·远程工作·流媒体·视音频
乾元8 分钟前
10 个可复制的企业级项目:从需求到交付的 AI 网络工程模板(深度实战版)
运维·网络·人工智能·网络协议·安全
遇见火星1 小时前
Linux 命令篇:df、du、fdisk 磁盘管理
linux·运维·服务器·df·du·fdisk
噎住佩奇1 小时前
正则表达式(Regex)入门
运维·正则表达式
运维行者_1 小时前
远程办公场景 NFA:从网络嗅探与局域网流量监控软件排查团队网络卡顿问题
运维·服务器·开发语言·网络·自动化·php
心丑姑娘2 小时前
怎么理解ClickHouse的向量化执行
java·服务器·clickhouse
成为你的宁宁2 小时前
【Zabbix运维监控实战(附图文教程):Nginx 服务可用性、连接请求状态、CPU 内存占用与 JVM(Jar 包 / Tomcat)全维度监控】
运维·jvm·nginx·zabbix
gaize12132 小时前
个人建站服务器完全指南:从基础认知到实操选型
运维·服务器
咕噜企业分发小米2 小时前
新人如何利用好云服务器
运维·服务器