在linux上使用epoll的Tcp客户端。 EPOLLIN事件没有多个连接

时间:2015-10-24 18:24:54

标签: c linux tcp network-programming epoll

在客户端应用中通过epoll接收数据时遇到问题。

我做了一个简单的插图代码。 Ommited最大错误处理逻辑。

简短的上下文说明:

  1. 客户端应用程序创建2个非阻塞套接字(SOCK_NON_BLOCK传递给套接字而不是通过fcntl)
  2. 客户端使用EPOLLOUT |向事件添加套接字EPOLLONESHOT和呼叫连接每个插座(非阻塞,所以我得到EINPROGRESS) 客户端等待epoll_wait建立连接(等待EPOLLOUT)
  3. 连接时 - 发送1个数据包请求(为了说明我使用example.com主机向google.com服务器发出HEAD请求)
  4. 发送时返回epoll通知过滤器切换到EPOLLIN
  5. 客户端等待数据读取(如果不是EAGAIN)并在第一个块重新加入后关闭套接字(确定)
  6. 问题

    只有一个套接字才能获得答案的消息。

    在tcpdump中,我看到Web服务器发送了两个答案( 这是tcpdump,突出显示了服务器的两个答案。所以请求都通过了,答案已经到来 http://pastie.org/10504786#59-78,89-109

    我用两个硬编码的谷歌ips准备了最简单的例子(为了简单起见,跳过名称解析)。

    似乎代码对于帖子来说有点大,所以这里的示例如下: http://pastie.org/10504718

    这是编译和输出:

    % gcc -std=c99 -Wall ./main.c && ./a.out
    assigned 4 for 173.194.32.135
    assigned 5 for 173.194.32.130
    socket 4
      write event
      data send 35 via 4
    socket 5
      write event
      data send 35 via 5
    socket 5
      read event
      read returned 258  <-- we have answer from first
    socket 5
      read event
      read returned 4294967295 
      read errno =9 errmesg= Bad file descriptor <--its ok cause we closed fd,but seems its event cached event 
    

    一只猫看到已建立2个连接,并且发送了两个请求,但只为一个套接字触发了读取事件。

    无法获得此类行为的情况,套接字配置似乎是独立的。

1 个答案:

答案 0 :(得分:0)

对我感到羞耻。

错误是在错误的事件数据初始化中。当切换到IN时,我忘了重新分配指针做相关的结构。所以所有开关都指向相同的数据。

错误代码

    //switching data listen
    ev.events = EPOLLIN | EPOLLONESHOT;
    epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);

http://pastie.org/10504718#83-85

    //switching data listen
    ev.data.ptr = c;
    ev.events = EPOLLIN | EPOLLONESHOT;
    epoll_ctl(epfd, EPOLL_CTL_MOD, c->fd, &ev);