如何将重叠I/O与套接字一起使用

How to use Overlapped I/O with sockets?

本文关键字:套接字 一起 重叠      更新时间:2023-10-16

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

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

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

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

  • 如果我想从其中一个客户端接收数据,我会使用WSARecv()并提供套接字句柄和一个要用接收到的数据填充的缓冲区,还提供一个回调函数。当数据被接收并填充到缓冲区时,回调函数将被调用,我可以处理数据
  • 当我想发送数据时,我使用WSASend(),我还提供了套接字句柄和回调函数,当数据被发送时(不确定是放在底层发送缓冲区中还是实际放在线路上),回调也会被调用,告诉我数据已经发送,我可以发送下一段数据

您似乎有一个误解,那就是OVERLAPPED回调实际上是同步的。

你说:

当数据被接收并填充到缓冲区时,回调函数将被称为

现实:

当调用可报警等待函数(例如SleepExMsgWaitForMultipleObjectsEx)时,如果数据已被接收并填充在缓冲区中,则回调函数将被称为

只要你意识到这一点,你就应该处于良好的状态。我同意您的观点,在您的场景中,带有回调的重叠I/O是一种很好的方法。因为回调发生在执行I/O的线程上,所以您不必担心同步来自多个线程的访问,就像在线程池中使用完成端口和工作项一样。

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

此外,可以保证每次返回0WSA_IO_PENDING的操作,无论该操作是否成功完成、被取消或出现其他错误,回调都会被排队一次。在回调发生之前,不能重用缓冲区。

IO完成回调机制运行良好,我已经使用过几次了,没有问题。在32位系统中,可以将套接字上下文实例的"this"放入OVERLAPPED结构的hEvent字段中,并在回调中检索它。不知道如何在64位系统中做到这一点:(