AcceptEx()
的文档说:
当这个操作成功完成时,sAcceptSocket可以被传递,但是只能用于以下function:
- ReadFile的
- WriteFile的
- 发送
- WSASend
- 的recv
- 的WSARecv
- 的TransmitFile
- closures套接字
- setsockopt(仅适用于SO_UPDATE_ACCEPT_CONTEXT)
请注意, shutdown()
不在列表中。 事实上,调用shutdown(sAcceptSocket, SD_SEND)
将返回SOCKET_ERROR
并且WSAGetLastError()
会产生错误WSAENOTCONN
:
发送或接收数据的请求被禁止,因为套接字未连接,并且(当使用sendto调用在数据报套接字上发送时)没有提供地址。
为什么不closures通过AcceptEx()
连接的套接字? 另外,为什么套接字没有显示为已连接,因为它已经在接收数据了(重叠操作已经完成,并且完成通知表明接收到了一些size>0
字节)?
你必须在AcceptEx()
完成之后调用setsockopt(SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT)
。 被接受的套接字与监听套接字的属性没有完全关联,因此在SO_UPDATE_ACCEPT_CONTEXT
被设置之前不会处于完全连接状态。 一些winsock API函数受到影响,包括getpeername()
, getsockname()
和shutdown()
。
如果使用ConnectEx()
进行出站连接,则必须在ConnectEx()
完成后调用setsockopt(SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT)
,然后才能使用shutdown()
。 这是MSDN上记录的行为 。 对于AcceptEx()
和SO_UPDATE_ACCEPT_CONTEXT
,它并没有这么说,但是shutdown()
对AcceptEx()
接受的套接字也有类似的限制。