epoll并发服务器(TCP)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> 
#include <arpa/inet.h>

#include <sys/epoll.h>

int main()
{
    int listenfd;
    int connfd;
    int ret;
    int i;
    int j;
    char buf[128];
    struct sockaddr_in srvaddr;
    struct sockaddr_in cltaddr;
    socklen_t addrlen;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    printf("create socket success !\n");

    memset(&srvaddr, 0, sizeof(srvaddr));
    srvaddr.sin_family = AF_INET;
    srvaddr.sin_port = htons(8888);
    srvaddr.sin_addr.s_addr = inet_addr("0.0.0.0");

    ret = bind(listenfd, (const struct sockaddr *)&srvaddr, sizeof(srvaddr));
    if (-1 == ret) {
        perror("bind");
        return -1;
    }
    printf("srv bind success !\n");

    ret = listen(listenfd, 1024);
    if (-1 == ret) {
        perror("listen");
        return -1;
    }
    printf("listen success\n");

    int epfd;
    epfd = epoll_create(1024);    
    if (-1 == epfd) {
        perror("epoll_create");
        return -1;
    }

   
    struct epoll_event event;    //需要添加的事件和文件描述符;
    event.events = EPOLLIN;      //事件
    event.data.fd = listenfd;    //文件描述符
    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &event);
    if (-1 == ret ) {
        perror("epoll_ctl");
        return -1;
    }

    struct epoll_event events[1024];    //用来存储检测到的事件和文件描述符的集合
    while(1)
    {
        ret = epoll_wait(epfd, events, 1024, 5000);
        if (ret == -1) {
            perror("epoll");
            return -1;
        }
        else if (0 == ret) {
            printf("epoll timeout ....\n");
            continue;
        }

        for (i = 0; i < ret; i++)
        {
            int fd = events[i].data.fd;    
            if (events[i].events == EPOLLIN)
            {    
                //判断是否为读事件
                if (fd == listenfd)
                {    
                    //判断是否为监听套接字,如果是监听套接字则建立新的通信连接;
                    addrlen = sizeof(struct sockaddr_in);
                    connfd = accept(listenfd, (struct sockaddr*)&cltaddr, &addrlen);
                    if (-1 == connfd)
                    {
                        perror("accept");
                        return -1;
                    }
                    printf("IP : %s -- PORT : %d\n", inet_ntoa(cltaddr.sin_addr) ,\ ntohs(cltaddr.sin_port));
                    printf("accept connfd = %d success \n", connfd);

                    //连接成功则将通信套接字添加到epoll实例中
                    event.events = EPOLLIN;
                    event.data.fd = connfd;
                    ret = epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &event);
                    if (-1 == ret ) {
                        perror("epoll_ctl");
                        return -1;
                    }
                }
                else
                {   
                    //如果是通信套接字,则处理客户端的数据请求。
                    memset(buf, 0, sizeof(buf));
                    ret = read(fd, buf, sizeof(buf));
                    if (-1 == ret) {
                        perror("read");
                        return -1;
                    }
                    else if (0 == ret) 
                    {
                        printf("client quit\n");
                        //将退出的套接字文件描述符从epoll实例中清除
                        event.events = EPOLLIN;
                        event.data.fd = fd;
                        ret = epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &event);
                        if (-1 == ret ) {
                            perror("epoll_ctl");
                            return -1;
                        }
                        close(fd);
                        continue;
                    }
                    printf("buf : %s\n", buf);
                }
            }
        }  
    }   
    close(listenfd);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值