免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2852 | 回复: 4
打印 上一主题 下一主题

一个简单的sock i/o程序,客户端用epoll,陷入了死循环 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-02 12:32 |只看该作者 |倒序浏览
5可用积分
本帖最后由 donet8 于 2012-03-02 12:37 编辑

一个程序里面,父进程是服务器端,创建一个子进程当客户端。
服务器端每隔1s钟发送一个消息,子进程接受并打印出来。

但我运行的结果却是:
Get EPOLLIN
Get EPOLLIN
Get EPOLLIN
Get EPOLLIN
Get EPOLLIN
Get EPOLLIN
Get EPOLLIN
不断打印。

代码的问题在哪儿? 我怀疑我epoll模型用的不对。网上说epoll_wait之后要重新epoll_ctl,这个是可选的还是必须做的?

  1. #include<arpa/inet.h>
  2. #include<signal.h>
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<sys/epoll.h>
  6. #include<sys/socket.h>
  7. #include<sys/types.h>
  8. #include<unistd.h>
  9. void server(void)
  10. {
  11.     int sockSrv=socket(AF_INET,SOCK_STREAM,0);
  12.     if(sockSrv==-1)return;
  13.     sockaddr_in sAddr;
  14.     sAddr.sin_family=AF_INET;
  15.     sAddr.sin_port =htons(34567);
  16.     sAddr.sin_addr.s_addr =htonl(INADDR_ANY);
  17.     if(-1 == bind( sockSrv, (sockaddr*)&sAddr, sizeof( sockaddr )))return;
  18.     if(-1 == listen(sockSrv,0))return;
  19.     socklen_t cbAddr = sizeof(sockaddr);
  20.     while(1){
  21.         int iAccSock = accept(sockSrv, (sockaddr*)&sAddr, &cbAddr );
  22.         if(iAccSock==-1)return;
  23.         printf("Server: Accepted!\n");
  24.         long i=0;
  25.         while(1){
  26.             char buf[6]={0};
  27.             sprintf(buf,"%d",++i);
  28.             if(-1 == send(iAccSock,buf,strlen(buf),0) ){
  29.                 printf("Server: send error\n");
  30.                 close(iAccSock);
  31.                 break;
  32.             }
  33.             printf("Server: data sent=%s\n",buf);
  34.             sleep(1);
  35.         }
  36.         close(iAccSock);
  37.     }
  38. }
  39. int createPoll(int hClient)
  40. {
  41.     int fd_epoll = epoll_create(1);
  42.     if(fd_epoll==-1)
  43.     {
  44.         printf("epoll_create failed\n");
  45.         return 0;
  46.     }
  47.     epoll_event ee;
  48.     ee.events=EPOLLIN;
  49.     int ret=epoll_ctl(fd_epoll,EPOLL_CTL_ADD,hClient,&ee);
  50.     if(ret==-1)
  51.     {
  52.         printf("epoll_ctl failed\n");
  53.         return 0;
  54.     }
  55.     while(true)
  56.     {
  57.         int fd=epoll_wait(fd_epoll,&ee,1,-1);
  58.         if(fd<0)
  59.         {
  60.             printf("epoll_wait error\n");
  61.             continue;
  62.         }
  63.         if(ee.events&EPOLLIN)
  64.         {
  65.         printf("Got EPOLLIN\n");
  66.             if(ee.data.fd==hClient)
  67.             {
  68.                 char buf[1024]={0};
  69.                 if(0>=recv(hClient,buf,sizeof(buf),0)){
  70.                     printf("Client: recv error\n");
  71.                     break;
  72.         }
  73.                 printf("Client: recv=%s\n",buf);
  74.             }
  75.         }
  76.     }//end while
  77. }

  78. void client(void)
  79. {
  80.     int hClient=socket(AF_INET,SOCK_STREAM,0);
  81.     if(hClient==-1)return;
  82.     sockaddr_in sAddr;
  83.     sAddr.sin_family=AF_INET;
  84.     sAddr.sin_port  =htons(34567);
  85.     sAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
  86.     if( -1==connect( hClient, (sockaddr*)&sAddr, sizeof(sockaddr) ) )
  87.     {
  88.         printf("Client: Async connect error\n");
  89.         return;
  90.     }

  91.     printf("Client: Connected\n");
  92.     createPoll(hClient);
  93.     close(hClient);
  94.     return;
  95. }

  96. int main(void)
  97. {
  98.     pid_t pid=fork();
  99.     if(pid==0)
  100.     {//child
  101.     sleep(1);
  102.         client();
  103.     }
  104.     else//father
  105.     {
  106.         server();
  107.     }
  108.     return 0;
  109. }
复制代码

最佳答案

查看完整内容

不了解怎么回事但是if ( ee.data.fd == hClient )没有这个条件的时候可以正常输出或者struct epoll_event ee;ee.events = EPOLLIN;ee.data.fd = hClient;且if ( ee.data.fd == hClient )也可以正常输出。

论坛徽章:
0
2 [报告]
发表于 2012-03-02 12:33 |只看该作者
不了解怎么回事

但是
if ( ee.data.fd == hClient )
没有这个条件的时候可以正常输出

或者
struct epoll_event   ee;
ee.events = EPOLLIN;
ee.data.fd = hClient;

if ( ee.data.fd == hClient )
也可以正常输出。

论坛徽章:
0
3 [报告]
发表于 2012-03-02 16:13 |只看该作者
ee.data.fd = hClient;加入47行后边

论坛徽章:
0
4 [报告]
发表于 2012-03-02 16:15 |只看该作者
源码修改了一下,如下

#include<arpa/inet.h>
#include<signal.h>
#include<stdio.h>
#include<string.h>
#include<sys/epoll.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

void server(void)
{
    int sockSrv=socket(AF_INET,SOCK_STREAM,0);
    if(sockSrv==-1)return;
    struct 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, (struct sockaddr*)&sAddr, sizeof( struct sockaddr )))return;
    if(-1 == listen(sockSrv,0))return;
    socklen_t cbAddr = sizeof(struct sockaddr);
    while(1){
        int iAccSock = accept(sockSrv, (struct 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 error\n");
                close(iAccSock);
                break;
            }
            printf("Server: data sent=%s\n",buf);
            sleep(1);
        }
        close(iAccSock);
    }
}
int createPoll(int hClient)
{
    printf("hClient = %d\n", hClient);
    int fd_epoll = epoll_create(1);
    if(fd_epoll==-1)
    {
        printf("epoll_create failed\n");
        return 0;
    }
    struct epoll_event ee;
    ee.data.fd = hClient;
    ee.events=EPOLLIN;
    printf("fd_epoll = %d\n", fd_epoll);
    int ret=epoll_ctl(fd_epoll,EPOLL_CTL_ADD,hClient,&ee);
    if(ret==-1)
    {
        printf("epoll_ctl failed\n");
        return 0;
    }
    while(1)
    {
        int fd=epoll_wait(fd_epoll,&ee,1,-1);
        if(fd<0)
        {
            printf("epoll_wait error\n");
            continue;
        }
        if(ee.events&EPOLLIN)
        {
            printf("Got EPOLLIN\n");
            printf("event.data.fd = %d\n", ee.data.fd);
            //if(ee.data.fd==hClient)
            {
                char buf[1024]={0};
                if(0>=recv(hClient,buf,sizeof(buf),0)){
                    printf("Client: recv error\n");
                    break;
                }
                printf("Client: recv=%s\n",buf);
            }
        }
    }//end while
}

void client(void)
{
    int hClient=socket(AF_INET,SOCK_STREAM,0);
    if(hClient==-1)return;
    struct 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, (struct sockaddr*)&sAddr, sizeof(struct sockaddr) ) )
    {
        printf("Client: Async connect error\n");
        return;
    }

    printf("Client: Connected\n");
    createPoll(hClient);
    close(hClient);
    return;
}

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

论坛徽章:
0
5 [报告]
发表于 2012-03-02 16:55 |只看该作者
:wink没有分
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP