【问题标题】:Using IOCP with send() and recv()将 IOCP 与 send() 和 recv() 一起使用
【发布时间】:2016-02-05 21:43:38
【问题描述】:

我正在尝试找出处理与我的 C++ TCP 服务器的多个连接的最佳方法。我偶然发现了epoll(),但遗憾的是它只适用于 Linux,我在 Windows 上做所有事情。

经过一些研究,在 Windows 上处理套接字的最佳方法似乎是使用 I/O 完成端口。我想使用它们,但是客户端应用程序使用send()recv()(我无法更改),这意味着我还需要使用相同的函数来发送和接收来自客户端的数据。这些函数似乎没有用于 IOCP(使用WSASend() / WSARecv() 代替)。

我想知道是否还有任何方法可以将 IOCP 与 send()recv() 一起使用?还是我应该看看其他方法?

【问题讨论】:

标签: c++ sockets iocp


【解决方案1】:

我还需要使用相同的函数向客户端发送和接收数据

这是不正确的。客户端不知道您如何将数据传入和传出 TCP 连接,无论是通过网络发送相同的确切 TCP 段的方式。

如果您的服务器受 I/O 限制,那么 WSAAsyncSelect 和/或 WSAEventSelect 工作得很好(并为您省去了多线程的麻烦)。 IOCP 仅适用于计算密集型服务,因为它们将工作项分配到可用线程,因此并发请求可以启动并在多个处理器内核上进行计算。

WSAPoll 是另一种选择。

【讨论】:

  • 我读到了 WSAPoll,它似乎是 Windows 的 epoll() 等价物,但它似乎有问题,微软不会修复它。
  • @Spook:我刚刚再次阅读了该投诉,是的,它的行为与 Linux poll 完全不同,尤其是在连接尝试失败方面。但是,合同是“遵循文档”而不是“与不同操作系统上具有不同名称的函数的确切行为相匹配”,并且看起来它的行为确实与记录的一样。所以你可以称之为一个不幸的设计决定,但不是一个错误。无论如何,如果它困扰您,请使用我提到的其他三种方法中的任何一种。
  • 好的,谢谢您的回复!过去我曾尝试使用带有 HWND 的 WSAAsyncSelect 来接收通知,它确实工作得很好,我只是认为 IOCP 会是一个更好的选择。另外,您是说可以使用 send() 并使用 WSARecv() 接收吗?这对我来说似乎不太可能,但我宁愿在编写实现它的代码之前在这里问一下。
  • “你是说可以使用 send() 并使用 WSARecv() 接收吗?” 绝对有可能。您是否停下来想过您所期望的意味着使用 IOCP 构建的每个 Web 服务器只能由也使用 IOCP 的 Windows Web 浏览器使用?那将使 IOCP 完全无用。幸运的是,有一些网络标准允许不同的操作系统和不同的 API 相互通信,只要它们都符合 TCP RFC。
  • 嗯,这对我来说似乎不太可能,但这是个好消息,因为这将允许我在使用 WSASend() / WSARecv() 时使用 IOCP,即使客户端使用 send() 和接收()。 “您是否停下来认为您所期望的意味着使用 IOCP 构建的每个 Web 服务器只能由也使用 IOCP 的 Windows Web 浏览器使用” 不是真的,但我挑战你找到任何现有的使用 send 的文章/代码() 在客户端,并在使用 IOCP 时在服务器端使用 WSARecv() 接收。非常感谢您解决这个问题!
猜你喜欢
  • 2012-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 2014-05-05
  • 2017-08-17
  • 2011-03-20
  • 2020-12-08
相关资源
最近更新 更多