Windows socket编程
IOCP
Windows下的异步IO模型 是通过 主线程投递任务
PostQueuedCompletionStatus()
-> 工作线程获取GetQueuedCompletionStatus()
并处理任务并反馈作业消息 ->主线程接收通知并在此投递.异步地处理网络事件.
在调用 AcceptEx 接受连接后,每个连进来的socket都会绑定有一个重叠结构体.向系统投递任务这一结构体用来标识该任务时使用了异步机制,即表明该事件是IOCP事件.
重叠体(重叠结构体)
包含用于异步(或重叠)输入和输出 (I/O) 的信息.
AcceptEx 比 Accept 强三点:
(1)最关键的是 AcceptEx 在客户端连入之前, 就把客户端的 Socket 建立好了, 也就是说, AcceptEx 是先建立Socket, 然后发出的 AcceptEx 调用, 也就是说, 在进行客户端的通信之前, 无论是否有客户端连入,Socket 都是提前建立好的, 而不需要像 accept 是在客户端连入之后, 在现场花费时间建立 Socket.
(2)相比 Accept 只能阻塞方式建立一个连入的入口, 对于大量的并发客户端来讲, 会出先连入因为链接连接过度处理不过来时发生堵塞等待这一现象,而 AcceptEx 可以在完成端口上投递多个请求, 还有客户端连入的时候, 就非常从容地去接受连接.
(3)AcceptEx 还有一个优点, 就是投递 AccepEx 的时候, 收取客户端发来的第一组数据, 这是同时进行的, 也就意味着, 如果客户端只是连入但不发送数据的话, 我们就不会收到这个 AccepeEx 完成的通知,异步的 AcceptEx 使用起来比 accept 要麻烦。
AcceptEx() 接受连接优化
不使用
WSAloctl()
函数将AcceptEx()加载到内存中的情况下,每次由连接连入系统都会从Mswsocket.lib中重新载入AcceptEx()函数处理连接.在由多个客户端频繁断开连入时,这样是十分低效率的.--来自MSDN.
解决办法
调用
WSAloctl()
函数预先将AcceptEx()
一次性载入到内存当中,在再次发生调用时通过lpfnAcceptEx
指针调用已加载到内存中的AcceptEx()
来处理连接任务. --MSDN优化建议.