求助epoll 用法

god510 2014-05-24 07:21:02
调用完epoll_wait 是否会清空之前注册的事件了? 如果清空的话,是否在每次调用完后,都必须得在调用epoll_ctl 的EPOLL_CTL_MOD 方法来重新把事件注册进去
...全文
137 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
god510 2014-05-26
  • 打赏
  • 举报
回复
91 行nRet 到处使用导致 for 检查epoll_wait 的返回改变。 纠结了好久。
qq120848369 2014-05-24
  • 打赏
  • 举报
回复
可以看一下我的网络库:https://code.csdn.net/qq120848369/simple_io/tree/master
god510 2014-05-24
  • 打赏
  • 举报
回复
我把163行 注释掉,也就是epoll_wait 后,不使用EPOLL_CTL_MOD 关注事件, 用telnet 测会出现莫名其妙的错误。 能帮看下哪出问题了吗
god510 2014-05-24
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <sys/epoll.h>  // epoll_create
#include <string.h>
#include <errno.h>
#include <stdlib.h>   // for atoi

#include <sys/socket.h>   // for socket
#include <sys/types.h>
#include <arpa/inet.h>

#include <unistd.h>  // for sleep


#define ERRMSG(MSG) printf("%s failed[%s]\n", #MSG, strerror(errno))
#define LISTEN_PORT 10000

#define TRUEERRMSG(MSG) \
do{\
    if(MSG) \
    { \
        printf("%s failed[%s]\n", #MSG, strerror(errno)); \
        return -1; \
    } \
}while(0)

typedef struct
{
    int nfd;
    int nDataLen;
    char szData[0];   
}ClientInfo;

int main(int argc, char **argv)
{
    int nRet;
    int nListenPort;
    int nEpollSize = 5;
    if(argv[1] != NULL)
    {
        nListenPort = atoi(argv[1]);
    }
    else
    {
        nListenPort = LISTEN_PORT;
    }

    int nListenFD = socket(AF_INET, SOCK_STREAM, 0);
    if(nListenFD == -1)
    {
        ERRMSG(socket);
        return -1;
    }

    struct sockaddr_in stSerAddr;
    stSerAddr.sin_family = AF_INET;
    stSerAddr.sin_port = htons(nListenPort);
    stSerAddr.sin_addr.s_addr = htonl( INADDR_ANY);

    int ireuseadd_on = 1;//支持端口复用 
    setsockopt(nListenFD, SOL_SOCKET, SO_REUSEADDR, &ireuseadd_on, sizeof(ireuseadd_on) );  

    nRet = bind(nListenFD, (struct sockaddr *)&stSerAddr, sizeof(stSerAddr));
    if(nRet == -1)
    {
        ERRMSG(bind);
        return -1;
    }

    nRet = listen(nListenFD, 1);
    TRUEERRMSG(nRet == -1&&"listen");

    int nefd = epoll_create(nEpollSize);
    if(nefd == -1)
    {
        ERRMSG(epoll_create);
        return -1;
    }

    struct epoll_event stEvent;
    stEvent.data.u64 = 0;
	stEvent.data.fd = nListenFD;

    stEvent.events = EPOLLIN;
    nRet = epoll_ctl(nefd, EPOLL_CTL_ADD, nListenFD, &stEvent); 
    TRUEERRMSG(nRet == -1&&"epoll_ctl");

    struct epoll_event aEpollEvents[5];
    int nTimeout = 10;
    while(1)
    {
        nRet = epoll_wait(nefd, aEpollEvents, 5, nTimeout);
        if(nRet <= 0)
        {
            continue;
        }
        for(int i = 0; i < nRet; i++)
        {

            if(aEpollEvents[i].events & EPOLLERR)
            {
                struct epoll_event stEvent;
                stEvent.data.u64 = 0;
				stEvent.data.fd = aEpollEvents[i].data.fd;
                stEvent.events = EPOLLIN | EPOLLERR | EPOLLHUP;
                nRet = epoll_ctl(nefd, EPOLL_CTL_DEL, aEpollEvents[i].data.fd, &stEvent);
                printf("EPOLL_CTL_DEL111111[%d][%s]fd[%d]\n", nRet, strerror(errno), aEpollEvents[i].data.fd);
                close(aEpollEvents[i].data.fd);
                continue;
            }
			if((aEpollEvents[i].events & EPOLLIN) == 0)
			{
				printf("not event \n");
				continue;
			}
            if(aEpollEvents[i].data.fd == nListenFD)
            { 
            // process new client connect
                printf("listen fd event accept nlistenfd[%d]\n", nListenFD);
                struct sockaddr_in stSockAddr;
                socklen_t nLen =  sizeof(stSockAddr);
                int nfd = accept(nListenFD, (struct sockaddr*)&stSockAddr, &nLen);
                if(nfd == -1)
                {
                    printf("accept failed[%s]\n", strerror(errno));
                    continue;
                }
                printf("client[%s:%d] connect fd[%d]\n", inet_ntoa(stSockAddr.sin_addr), ntohs(stSockAddr.sin_port), nfd);
                struct epoll_event stEvent;
                stEvent.data.u64 = 0;
				stEvent.data.fd = nfd;
                stEvent.events = EPOLLIN | EPOLLERR | EPOLLHUP;
                nRet = epoll_ctl(nefd, EPOLL_CTL_ADD, nfd, &stEvent);
				continue;
            }
            
            if(aEpollEvents[i].events & EPOLLIN)
            {
            // process read event`
                char szBuff[1024] = {0};
                nRet = recv(aEpollEvents[i].data.fd, szBuff, sizeof(szBuff), 0);
                if(nRet <= 0)
                {
					printf("recv [%d][%s]fd[%d]\n", nRet, strerror(errno), aEpollEvents[i].data.fd);
                    struct epoll_event stEvent;
                    stEvent.data.u64 = 0;
					stEvent.data.fd = aEpollEvents[i].data.fd;
                    stEvent.events = 0;
                    nRet = epoll_ctl(nefd, EPOLL_CTL_DEL, aEpollEvents[i].data.fd, &stEvent);
                    printf("EPOLL_CTL_DEL[%d][%s] [%d]\n", nRet, strerror(errno), aEpollEvents[i].data.fd);
                    struct sockaddr_in stAddr;
                    socklen_t nLen = sizeof(stAddr);
                    nRet = getpeername(aEpollEvents[i].data.fd, (struct sockaddr*)&stAddr, &nLen);
                    printf("client[%s:%d] close connect nRet[%d][%s]fd[%d]\n", inet_ntoa(stAddr.sin_addr), ntohs(stAddr.sin_port), nRet, strerror(errno), aEpollEvents[i].data.fd);
                    close(aEpollEvents[i].data.fd);
                }
                else
                {
                    printf("recv[%s]fd[%d]\n", szBuff, aEpollEvents[i].data.fd);    
					struct epoll_event stEvent;
					stEvent.data.u64 = 0;
					stEvent.data.fd = aEpollEvents[i].data.fd;
					stEvent.events = EPOLLIN;
					nRet = epoll_ctl(nefd, EPOLL_CTL_MOD, aEpollEvents[i].data.fd, &stEvent);
					printf("EPOLL_CTL_MOD[%d][%s] [%d]\n", nRet, strerror(errno), aEpollEvents[i].data.fd);
                }

            }

        }
    }
    
    return 0;
}

就想叫yoko 2014-05-24
  • 打赏
  • 举报
回复
我只会水平触发,所以只说水平触发 mod后是一直关注的,如果不关注了,需要mod取消掉该事件 正在写的一个epoll库 参考下 https://code.csdn.net/q191201771/chef

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧