使用 WSARecv() 和 IOCP 时如何知道套接字何时收到了 FIN 数据包?
Posted
技术标签:
【中文标题】使用 WSARecv() 和 IOCP 时如何知道套接字何时收到了 FIN 数据包?【英文标题】:How to know when the socket has received a FIN packet when using WSARecv() and IOCP? 【发布时间】:2015-03-06 12:41:46 【问题描述】:当使用阻塞套接字和recv()
函数时,当套接字收到一个FIN包时,recv()
会返回0
。
但是,在使用WSARecv()
和IOCP时,如何知道socket何时收到了一个FIN包呢?我认为lpNumberOfBytesRecvd
也将设置为0
,但我不确定。
【问题讨论】:
【参考方案1】:如果FIN
到达时WSARecv()
调用正在进行,那么您将成功完成并将lpNumberOfBytesRecvd
设置为0。
如果在FIN
到达之后发起WSARecv()
调用,那么您可能会从WSARecv()
调用中收到WSAESHUTDOWN
错误。
当我获得第一个“客户端关闭”(即零字节读取返回)时,我倾向于在套接字上发出shutdown(s, SD_RECEIVE)
,因为这会给出上述可预测的行为并避免通过 IOCP 进行后续尝试接收...
【讨论】:
WSARecv()
返回错误时的错误代码是什么(即WSAGetLastError()
返回什么)?
在发出完成的情况下,如果对端正常断开连接(发送FIN
),则报告 0 字节的 I/O 成功。但是如果连接异常丢失,则会报告 I/O 失败并带有错误代码,例如ERROR_NETNAME_DELETED
(64)。确保您正在考虑套接字故障和异常断开连接。并非所有客户端都能正常断开连接,否则网络故障有时可能会丢失 FIN
。
是的,但这不是问题所在。 :) 完成失败的方式有很多...这实际上不是失败路径,而是读取 0 字节的成功路径。
我在FIN包到达后调用了WSARecv()
,WSARecv()
返回了0
,WSAGetLastError()
也返回了0
!
@RemyLebeau FIN 就像 TCP 数据段一样接受确认和重传。以上是关于使用 WSARecv() 和 IOCP 时如何知道套接字何时收到了 FIN 数据包?的主要内容,如果未能解决你的问题,请参考以下文章
WSASend() 和 WSARecv() 的所有错误代码是不是意味着套接字已断开连接?
io 完成端口问题,每个 GetQueuedCompletionStatus 调用多个 wsarecv 或 wsasend