c - Linux 上带有 epoll 的 Tcp 客户端。 EPOLLIN 事件未因多个连接而上升

标签 c linux tcp network-programming epoll

在通过 epoll 从客户端应用程序的答案中接收数据时遇到问题。

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

简短的上下文描述:

  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)并在读取第一个 block 后关闭套接字(没问题)

问题:

只有一个 socket 得到答复已经到来的通知。

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

我准备了最简单的示例,其中包含两个硬编码的 google ip(为简单起见,跳过名称解析)。

似乎代码对于发布来说有点庞大,所以这里的例子: 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 个连接,并发送了两个请求,但只为一个套接字触发了读取事件。

无法了解这种行为的情况,套接字配置似乎是独立的。

最佳答案

我真丢人。

错误是错误的事件数据初始化。当切换到 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);

关于c - Linux 上带有 epoll 的 Tcp 客户端。 EPOLLIN 事件未因多个连接而上升,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33321756/

相关文章:

c++ - 覆盖 Ctrl-C

linux - 窗口生成器导出 jar : why does it look different from in eclipse

c - TCP服务器不等待客户端响应?

c - 多重处理

c - 正确解析 C 中的命令行参数

c - 如果条件是导致其他部分的调用方法

java - 在我的 WSL Kali linux 上安装 jdk 时出现语法错误

linux - 虚拟环境的概念

delphi - Indy TCPClient 和 InputBuffer 中的流氓字节

C#包结构系统