如何将重叠I/O与套接字一起使用
How to use Overlapped I/O with sockets?
我想在我的服务器中使用Overlapped I/O,但我找不到很多关于这个主题的教程(大多数教程都是关于带有完成端口的重叠I/O,我想使用回调函数)。
我的服务器一次最多连接400个客户端,并且它只在很长一段时间内发送和接收数据(每30秒,服务器和客户端之间就会交换几KB的数据)。
我想使用Overlapped I/O的主要原因是select()
最多只能处理64个套接字(我有400个!)。
所以我会告诉你我是如何理解重叠I/O的,如果我错了,我会纠正我:
- 如果我想从其中一个客户端接收数据,我会使用
WSARecv()
并提供套接字句柄和一个要用接收到的数据填充的缓冲区,还提供一个回调函数。当数据被接收并填充到缓冲区时,回调函数将被调用,我可以处理数据 - 当我想发送数据时,我使用
WSASend()
,我还提供了套接字句柄和回调函数,当数据被发送时(不确定是放在底层发送缓冲区中还是实际放在线路上),回调也会被调用,告诉我数据已经发送,我可以发送下一段数据
您似乎有一个误解,那就是OVERLAPPED回调实际上是同步的。
你说:
当数据被接收并填充到缓冲区时,回调函数将被称为
现实:
当调用可报警等待函数(例如
SleepEx
或MsgWaitForMultipleObjectsEx
)时,如果数据已被接收并填充在缓冲区中,则回调函数将被称为
只要你意识到这一点,你就应该处于良好的状态。我同意您的观点,在您的场景中,带有回调的重叠I/O是一种很好的方法。因为回调发生在执行I/O的线程上,所以您不必担心同步来自多个线程的访问,就像在线程池中使用完成端口和工作项一样。
哦,还要确保检查WSA_IO_PENDING
,因为如果缓冲区中有足够的数据(用于接收)或足够的空间(用于发送),则操作可以同步完成。在这种情况下,回调会发生,但它会排队等待下一个可提醒的等待,它永远不会立即运行。某些错误也将同步报告。其他人会来接你的电话。
此外,可以保证每次返回0
或WSA_IO_PENDING
的操作,无论该操作是否成功完成、被取消或出现其他错误,回调都会被排队一次。在回调发生之前,不能重用缓冲区。
IO完成回调机制运行良好,我已经使用过几次了,没有问题。在32位系统中,可以将套接字上下文实例的"this"放入OVERLAPPED结构的hEvent字段中,并在回调中检索它。不知道如何在64位系统中做到这一点:(
- 当套接字连接断开时检测C/C++Unix
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- 套接字读取后,我在缓冲区中看到意外输入
- 如何在CPP中创建应该在Windows和Linux上运行的套接字?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 套接字连接"Operation not permitted"错误,甚至使用升压/平发器根.cpp
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- (Winsock) UDP 接收工作正常,但同一套接字的发送失败
- MSG_WAITALL的套接字发送得到了 22 EINVAL
- C++套接字客户端到 Python 服务器未创建连接
- 在不知道套接字的情况下关闭网络连接
- C++套接字对不读/写父/子
- 如何使TCP套接字与SO_BINDTODEVICE(针对路由表)一起工作
- 如何将套接字与 Python 客户端和C++服务器一起使用
- 如何将重叠I/O与套接字一起使用
- 如何将非阻塞套接字与多个线程一起使用
- 有没有办法将QTcpSocket与现有套接字一起使用
- 套接字编码(与TeamSpeak一起工作)