当前位置:  技术问答>linux和unix

一个简单的epoll程序使得客户端死循环了,为什么?

    来源: 互联网  发布时间:2017-02-06

    本文导语:  再开一贴: 我的一个小程序里面,父进程是服务器端,创建一个子进程当客户端。  服务器端每隔1s钟发送一个消息,子进程接受并打印出来。     但我运行的结果却是:  Get EPOLLIN  Get EPOLLIN  Get EPOLLIN  Get EPOLLIN...

再开一贴: 我的一个小程序里面,父进程是服务器端,创建一个子进程当客户端。 
服务器端每隔1s钟发送一个消息,子进程接受并打印出来。 
  
但我运行的结果却是: 
Get EPOLLIN 
Get EPOLLIN 
Get EPOLLIN 
Get EPOLLIN 
Get EPOLLIN 
Get EPOLLIN 
Get EPOLLIN 
不断打印。 
  
代码的问题在哪儿? 我怀疑我epoll模型用的不对。网上说epoll_wait之后要重新epoll_ctl,这个是可选的还是必须做的? 


#include
#include
#include
#include
#include
#include
#include
#include
void server(void)
{
    int sockSrv=socket(AF_INET,SOCK_STREAM,0);
    if(sockSrv==-1)return;
    sockaddr_in sAddr;
    sAddr.sin_family=AF_INET;
    sAddr.sin_port =htons(34567);
    sAddr.sin_addr.s_addr =htonl(INADDR_ANY);
    if(-1 == bind( sockSrv, (sockaddr*)&sAddr, sizeof( sockaddr )))return;
    if(-1 == listen(sockSrv,0))return;
    socklen_t cbAddr = sizeof(sockaddr);
    while(1){
        int iAccSock = accept(sockSrv, (sockaddr*)&sAddr, &cbAddr );
        if(iAccSock==-1)return;
        printf("Server: Accepted!n");
        long i=0;
        while(1){
            char buf[6]={0};
            sprintf(buf,"%d",++i);
            if(-1 == send(iAccSock,buf,strlen(buf),0) ){
                printf("Server: send errorn");
                close(iAccSock);
                break;
            }
            printf("Server: data sent=%sn",buf);
            sleep(1);
        }
        close(iAccSock);
    }
}
int createPoll(int hClient)
{
    int fd_epoll = epoll_create(1);
    if(fd_epoll==-1)
    {
        printf("epoll_create failedn");
        return 0;
    }
    epoll_event ee;
    ee.events=EPOLLIN;
    int ret=epoll_ctl(fd_epoll,EPOLL_CTL_ADD,hClient,&ee);
    if(ret==-1)
    {
        printf("epoll_ctl failedn");
        return 0;
    }
    while(true)
    {
        int fd=epoll_wait(fd_epoll,&ee,1,-1);
        if(fd=recv(hClient,buf,sizeof(buf),0)){
                    printf("Client: recv errorn");
                    break;
}
                printf("Client: recv=%sn",buf);
            }
        }
    }//end while
}

void client(void)
{
    int hClient=socket(AF_INET,SOCK_STREAM,0);
    if(hClient==-1)return;
    sockaddr_in sAddr;
    sAddr.sin_family=AF_INET;
    sAddr.sin_port  =htons(34567);
    sAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    if( -1==connect( hClient, (sockaddr*)&sAddr, sizeof(sockaddr) ) )
    {
        printf("Client: Async connect errorn");
        return;
    }

    printf("Client: Connectedn");
    createPoll(hClient);
    close(hClient);
    return;
}

int main(void)
{
    pid_t pid=fork();
    if(pid==0)
    {//child
sleep(1);
        client();
    }
    else//father
    {
        server();
    }
    return 0;
}

|
我没玩过 epoll,刚才在网上学习了下,呵呵

    epoll_event ee;
    ee.data.fd=hClient;
    ee.events=EPOLLIN;
    int ret=epoll_ctl(fd_epoll,EPOLL_CTL_ADD,hClient,&ee);

在epoll_ctl之前,加那么一句看看

|

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define CONN_MAX 65536
#define EV_BUF_SIZE 1024
#define E_READ      0x01
#define E_WRITE     0x02
#define RS_BUFF_SIZE 8197
static int epollfd = 0;
static int max_connections = 0;
static int lfd = 0;
static struct sockaddr_in sa = {0};        
static socklen_t sa_len = sizeof(struct sockaddr_in);
static int ev_sock_type = 0;
static int ev_sock_list[] = {SOCK_STREAM, SOCK_DGRAM};
static int ev_sock_count = 2;
static in_addr_t multicast_addr = INADDR_NONE;
typedef struct _CONN
{
    int fd;
    int x;
    int nout;
    int n;
    int keepalive;
    char out[EV_BUF_SIZE];
    char buffer[EV_BUF_SIZE];
}CONN;
static CONN *conns = NULL;
static char *out_block = NULL;
static char out_data[EV_BUF_SIZE];
static int out_data_len = 0;
static char kout_data[EV_BUF_SIZE];
static int kout_data_len = 0;
/* set rlimit */
char* GetHtml(const char *pFileName)
{}
int setrlimiter(char *name, int rlimit, int nset)
{
    int ret = -1;
    struct rlimit rlim;
    if(name)
    {
        if(getrlimit(rlimit, &rlim) == -1)
            return -1;
        else
        {
            fprintf(stdout, "getrlimit %s cur[%ld] max[%ld]n", 
                    name, (long)rlim.rlim_cur, (long)rlim.rlim_max);
        }
        if(rlim.rlim_cur > nset && rlim.rlim_max > nset)
            return 0;
        rlim.rlim_cur = nset;
        rlim.rlim_max = nset;
        if((ret = setrlimit(rlimit, &rlim)) == 0)
        {
            fprintf(stdout, "1: setrlimit %s cur[%ld] max[%ld]n",
                    name, (long)rlim.rlim_cur, (long)rlim.rlim_max);
            return 0;
        }
        else
        {
            fprintf(stderr, "2: setrlimit %s cur[%ld] max[%ld] failed, %sn",
                    name, (long)rlim.rlim_cur, (long)rlim.rlim_max, strerror(errno));
        }
    }
    return ret;
}

void ev_handler(int fd, int ev_flags, void *arg)
{
    int rfd = 0, n = 0, out_len = 0;
    struct         sockaddr_in rsa;
    socklen_t rsa_len = sizeof(struct sockaddr_in);
    struct epoll_event evp;
    char *out = NULL;

    if(fd == lfd )
    {
        if((ev_flags & E_READ))
        {
            while((rfd = accept(fd, (struct sockaddr *)&rsa, &rsa_len)) > 0)
            {
                conns[rfd].fd = rfd;
                /* set FD NON-BLOCK */
                conns[rfd].n = 0;
                fcntl(rfd, F_SETFL, fcntl(rfd, F_GETFL, 0)|O_NONBLOCK);
                memset(&evp, 0, sizeof(struct epoll_event));
                evp.data.fd = rfd;
                evp.events = EPOLLIN;
                epoll_ctl(epollfd, EPOLL_CTL_ADD, evp.data.fd, &evp);
            }
            return ;
        }
    }
    else
    {
        if(ev_flags & E_READ)
        {

            n = read(fd, conns[fd].buffer+conns[fd].n, EV_BUF_SIZE - conns[fd].n);
            if(n > 0)
            {
                conns[fd].n += n;
                conns[fd].buffer[conns[fd].n] = 0;
                if(strstr(conns[fd].buffer, "rnrn"))
                {
                    if(strcasestr(conns[fd].buffer, "Keep-Alive")) conns[fd].keepalive = 1;
                    conns[fd].x = 0;
                    conns[fd].n = 0;
                    memset(&evp, 0, sizeof(struct epoll_event));
                    evp.data.fd = fd;
                    evp.events = EPOLLOUT;
                    epoll_ctl(epollfd, EPOLL_CTL_MOD, evp.data.fd, &evp);
                }
            }                
            else
            {
                goto err;
            }
        }
        if(ev_flags & E_WRITE)
        {
            if(conns[fd].keepalive){out = kout_data;out_len = kout_data_len;}
            else {out = out_data; out_len = out_data_len;}
            n = write(fd, out + conns[fd].x, out_len - conns[fd].x);
            if(n > 0 )
            {
                conns[fd].x += n;
                if(conns[fd].x  0) ? connection_limit : CONN_MAX;
    /* Set resource limit */
    setrlimiter("RLIMIT_NOFILE", RLIMIT_NOFILE, CONN_MAX);        
    out_block = GetHtml("./Template.html");
    //printf("%srn", out_block);
    out_data_len = sprintf(out_data, "HTTP/1.0 200 OKrnContent-Length: %drnrn%s", (int)strlen(out_block), out_block);
    kout_data_len = sprintf(kout_data, "HTTP/1.0 200 OKrnConnection: Keep-AlivernContent-Length: %drnrn%s", (int)strlen(out_block), out_block);

    /* Initialize global vars */
    if((conns = (CONN *)calloc(CONN_MAX, sizeof(CONN))))
    {
        memset(&sa, 0, sizeof(struct sockaddr_in));        
        sa.sin_family = AF_INET;
        sa.sin_addr.s_addr = INADDR_ANY;
        sa.sin_port = htons(port);
        sa_len = sizeof(struct sockaddr_in );
        /* Initialize inet */ 
        lfd = socket(AF_INET, ev_sock_list[ev_sock_type], 0);
        if(setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR,
                    (char *)&opt, (socklen_t) sizeof(opt)) != 0
#ifdef SO_REUSEPORT
                || setsockopt(lfd, SOL_SOCKET, SO_REUSEPORT,
                    (char *)&opt, (socklen_t) sizeof(opt)) != 0
#endif
          )
        {
            fprintf(stderr, "setsockopt[SO_REUSEADDR] on fd[%d] failed, %s", fd, strerror(errno));
            _exit(-1);
        }
        /* Bind */
        if(bind(lfd, (struct sockaddr *)&sa, sa_len) != 0 )
        {
            //SHOW_LOG("Binding failed, %s", strerror(errno));
            return -1;
        }
        /* set FD NON-BLOCK */
        if(fcntl(lfd, F_SETFL, fcntl(lfd, F_GETFL, 0)|O_NONBLOCK) != 0 )
        {
            //SHOW_LOG("Setting NON-BLOCK failed, %s", strerror(errno));
            return -1;
        }
        /* Listen */
        if(ev_sock_list[ev_sock_type] == SOCK_STREAM)
        {
            if(listen(lfd, CONN_MAX) != 0 )
            {
                //SHOW_LOG("Listening  failed, %s", strerror(errno));
                return -1;
            }
        }
        /* set multicast */
        if(ev_sock_list[ev_sock_type] == SOCK_DGRAM && multicast_ip)
        {
            struct ip_mreq mreq;
            memset(&mreq, 0, sizeof(struct ip_mreq));
            mreq.imr_multiaddr.s_addr = multicast_addr = inet_addr(multicast_ip);
            mreq.imr_interface.s_addr = INADDR_ANY;
            if(setsockopt(lfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,(char*)&mreq, sizeof(mreq)) != 0)
            {
                //SHOW_LOG("Setsockopt(MULTICAST) failed, %s", strerror(errno));
                return -1;
            }
        }
        //SHOW_LOG("Initialize evbase ");
        struct epoll_event evp, events[CONN_MAX];
        int flag = 0, n = 0;
        if((epollfd = epoll_create(CONN_MAX)) > 0)
        {
            memset(&evp, 0, sizeof(struct epoll_event));
            evp.data.fd = lfd;
            evp.events = EPOLLIN|EPOLLET;
            epoll_ctl(epollfd, EPOLL_CTL_ADD, lfd, &evp);
            do
            {
                n = epoll_wait(epollfd, events, CONN_MAX, -1);
                for(i = 0; i 

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • epoll中epoll_event结构体的含义
  • epoll_ctl(,EPOLL_CTL_DEL,); 的问题!!!
  • 第一次用epoll就傻眼,程序报create_epoll error Function not implemented
  • 为Qt添加epoll的高性能I/O复用 qt_eventdispatcher_epoll
  • epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event)为何老返回-1
  • epoll 退出
  • 关于epoll的几个疑问
  • 大家好,问个问题,关于EPOLL的。。。
  • epoll并发问题
  • 有人碰到过epoll丢信号吗
  • epoll异常问题
  • epoll模型如何限制最大连接数
  • epoll可读的问题
  • python实现Linux异步epoll代码
  • epoll多路复用模型的疑惑,请高手解答
  • epoll,socket超时如何设置?
  • epoll的一个问题
  • linux并发服务器中epoll+多线程分别怎么理解?
  • 关于epoll的链接库
  • 谁能解释一下epoll、libevent、zeroMQ的区别?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3