如何使用带套接字的重叠I / O?

时间:2015-02-22 16:27:34

标签: c++ windows sockets winapi network-programming

我想在我的服务器中使用Overlapped I / O,但是我找不到关于这个主题的很多教程(大多数教程都是关于带有完成端口的重叠I / O,我想使用回调函数)

我的服务器一次最多连接400个客户端,它只能在很长一段时间内发送和接收数据(每30秒在服务器和客户端之间交换几千字节的数据)。

我想使用重叠I / O的主要原因是因为select()最多只能处理64个套接字(而且我有400个!)。

所以我会告诉你我如何理解重叠I / O并纠正我,如果我错了:

  • 如果我想从其中一个客户端接收数据,我使用WSARecv()并提供套接字句柄,并使用接收数据填充缓冲区,并且我还提供回调函数< / strong>即可。当数据被接收并填入缓冲区时,将调用回调函数,我可以处理数据。
  • 当我想发送数据时,我使用WSASend(),我还提供套接字句柄和回调函数,以及何时发送数据(不确定是否放置在底层发送缓冲区中或实际放置在(),也会调用回调告诉我数据已发送,我可以发送下一条数据。

2 个答案:

答案 0 :(得分:2)

你似乎有一个误解,即OVERLAPPED回调实际上是同步的。

你说:

  

当接收到数据并填入缓冲区时,将调用回调函数

现实:

  

当对可警告的等待函数(例如SleepExMsgWaitForMultipleObjectsEx)进行调用时,如果已经接收到数据并填充在缓冲区中,则将调用回调函数

只要你意识到这一点,你应该保持良好状态。我同意你的观点,在你的场景中,重复I / O与回调是一种很好的方法。因为回调发生在执行I / O的线程上,所以您不必担心从多个线程同步访问,这需要完成端口和线程池上的工作项所需的方式。

哦,还要确保检查WSA_IO_PENDING,因为如果有足够的数据已经缓冲(用于接收)或缓冲区中有足够的空间,操作可以同步完成(发送)。在这种情况下,将发生回调,但它会排队等待下一个可警告的等待,它永远不会立即运行。某些错误也将同步报告。其他人会回复你。

此外,它确保您的回调在每个返回0WSA_IO_PENDING的操作中排队一次,无论该操作是否成功完成,是否已取消,或者是否有其他错误。在回调发生之前,您无法重用缓冲区。

答案 1 :(得分:0)

IO完成回调机制工作正常,我已经使用了几次,没问题。在32位系统中,您可以将套接字上下文实例的“this”放入OVERLAPPED结构的hEvent字段中,并在回调中检索它。不确定如何在64位系统中执行此操作:(