dopamone 2023-10-20 09:52 采纳率: 0%
浏览 6

c++使用poll改成epoll遇到问题

带佬们能帮我看一下我有没有理解错下面的代码吗?
poll的是别人库里面写的,然后我改成使用epoll的方式,他这个就是用poll去监听某一个sock吧,但是我印象中应该是监听很多sock才对,反正跟着他的这种方式写了个epoll版本的,但是现在epoll这种方式传输文件到一半就没了,不知道怎么回事
带佬们帮忙看看呗,谢谢啦

inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {
#ifdef CPPHTTPLIB_USE_POLL
  struct pollfd pfd_read;
  pfd_read.fd = sock;
  pfd_read.events = POLLOUT;

  auto timeout = static_cast<int>(sec * 1000 + usec / 1000);

  return handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); });

#elifdef CPPHTTPLIB_USE_EPOLL
  int epollfd;
  struct epoll_event event[EPOLLEVENTS];
  struct epoll_event ev;
  auto timeout = static_cast<int>(sec * 1000 + usec / 1000);

  epollfd = epoll_create(FDSIZE);
  ev.events = EPOLLOUT;
  ev.data.fd = sock;
  epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev);
  return handle_EINTR([&](){return epoll_wait(epollfd, event, 1000, timeout); });

/*hanle_EINTR*/
template <typename T> inline ssize_t handle_EINTR(T fn) {
  ssize_t res = 0;
  while (true) {
    res = fn();
    if (res < 0 && errno == EINTR) { continue; }
    break;
  }
  return res;
}
  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-20 12:45
    关注

    【以下回答由 GPT 生成】

    对于你的问题,我注意到你在使用epoll时遇到了一些问题。以下是我对你的代码进行的一些分析和建议。

    在你的代码中,你创建了一个epoll实例并注册了一个EPOLLOUT事件。在每次调用epoll_wait时,你都会检查是否有就绪的事件,并在事件列表中进行处理。然而,我注意到你的代码中没有为就绪的事件做任何处理。这可能导致你的文件传输中断的问题。

    为了解决这个问题,你可以在处理就绪的事件时执行相应的操作。例如,在EPOLLOUT事件就绪时,你可以继续发送文件数据。

    另外,你在调用epoll_wait时指定了一个超时时间,但是你的代码中似乎没有对超时情况进行处理。你可以在超时后采取适当的措施来处理超时情况,比如关闭套接字并中断文件传输。

    下面是一个可能的解决方案的示例代码:

    int epollfd;
    struct epoll_event event[EPOLLEVENTS];
    
    // 创建 epoll 实例
    epollfd = epoll_create(FDSIZE);
    
    struct epoll_event ev;
    ev.events = EPOLLOUT;
    ev.data.fd = sock;
    
    // 将套接字加入到 epoll 实例中
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &ev) == -1) {
      // 添加套接字失败,处理错误情况
      // 将错误信息写入日志或进行其他处理
      // ...
    }
    
    while (true) {
      // 等待事件就绪
      int num_events = epoll_wait(epollfd, event, EPOLLEVENTS, timeout);
    
      // 检查 epoll_wait 的返回值
      if (num_events == -1) {
        if (errno == EINTR) {
          // 检测到信号中断,重新等待事件就绪
          continue;
        } else {
          // epoll_wait 失败,处理错误情况
          // 将错误信息写入日志或进行其他处理
          // ...
          break;
        }
      } else if (num_events == 0) {
        // 超时情况处理
        // 关闭套接字并中断文件传输
        // ...
        break;
      }
    
      // 处理就绪事件
      for (int i = 0; i < num_events; i++) {
        if (event[i].events & EPOLLOUT) {
          // EPOLLOUT 事件就绪,继续发送文件数据
          // ...
          // 如果文件传输完成,关闭套接字
          // ...
        }
      }
    }
    
    // 关闭 epoll 实例
    close(epollfd);
    

    上述代码给出了一个基本的epoll使用示例,你可以根据你的需求进行相应的修改和扩展。请注意,这只是一个示例,可能不完全符合你的实际需求,请根据自己的情况进行适当调整。

    希望这个解决方案对你有帮助!如果你有任何其他问题,请随时提问。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 10月20日

悬赏问题

  • ¥15 如何构建全国统一的物流管理平台?
  • ¥100 ijkplayer使用AndroidStudio/CMake编译,如何支持 rtsp 直播流?
  • ¥20 和学习数据的传参方式,选择正确的传参方式有关
  • ¥15 这是网络安全里面的poem code
  • ¥15 用js遍历数据并对非空元素添加css样式
  • ¥15 使用autodl云训练,希望有直接运行的代码(关键词-数据集)
  • ¥50 python写segy数据出错
  • ¥20 关于线性结构的问题:希望能从头到尾完整地帮我改一下,困扰我很久了
  • ¥30 3D多模态医疗数据集-视觉问答
  • ¥20 设计一个二极管稳压值检测电路