我想在我的服务器中使用Overlapped I / O,但是我找不到关于这个主题的很多教程(大多数教程都是关于带有完成端口的重叠I / O,我想使用回调函数)
我的服务器一次最多连接400个客户端,它只能在很长一段时间内发送和接收数据(每30秒在服务器和客户端之间交换几千字节的数据)。
我想使用重叠I / O的主要原因是因为select()
最多只能处理64个套接字(而且我有400个!)。
所以我会告诉你我如何理解重叠I / O并纠正我,如果我错了:
WSARecv()
并提供套接字句柄,并使用接收数据填充缓冲区,并且我还提供回调函数< / strong>即可。当数据被接收并填入缓冲区时,将调用回调函数,我可以处理数据。WSASend()
,我还提供套接字句柄和回调函数,以及何时发送数据(不确定是否放置在底层发送缓冲区中或实际放置在(),也会调用回调告诉我数据已发送,我可以发送下一条数据。答案 0 :(得分:2)
你似乎有一个误解,即OVERLAPPED回调实际上是同步的。
你说:
当接收到数据并填入缓冲区时,将调用回调函数
现实:
当对可警告的等待函数(例如
SleepEx
或MsgWaitForMultipleObjectsEx
)进行调用时,如果已经接收到数据并填充在缓冲区中,则将调用回调函数
只要你意识到这一点,你应该保持良好状态。我同意你的观点,在你的场景中,重复I / O与回调是一种很好的方法。因为回调发生在执行I / O的线程上,所以您不必担心从多个线程同步访问,这需要完成端口和线程池上的工作项所需的方式。
哦,还要确保检查WSA_IO_PENDING
,因为如果有足够的数据已经缓冲(用于接收)或缓冲区中有足够的空间,操作可以同步完成(发送)。在这种情况下,将发生回调,但它会排队等待下一个可警告的等待,它永远不会立即运行。某些错误也将同步报告。其他人会回复你。
此外,它确保您的回调在每个返回0
或WSA_IO_PENDING
的操作中排队一次,无论该操作是否成功完成,是否已取消,或者是否有其他错误。在回调发生之前,您无法重用缓冲区。
答案 1 :(得分:0)
IO完成回调机制工作正常,我已经使用了几次,没问题。在32位系统中,您可以将套接字上下文实例的“this”放入OVERLAPPED结构的hEvent字段中,并在回调中检索它。不确定如何在64位系统中执行此操作:(