【发布时间】:2015-03-06 12:41:46
【问题描述】:
当使用阻塞套接字和recv()函数时,当套接字收到一个FIN包时,recv()会返回0。
但是,在使用WSARecv()和IOCP时,如何知道socket何时收到了一个FIN包呢?我认为lpNumberOfBytesRecvd 也将设置为0,但我不确定。
【问题讨论】:
当使用阻塞套接字和recv()函数时,当套接字收到一个FIN包时,recv()会返回0。
但是,在使用WSARecv()和IOCP时,如何知道socket何时收到了一个FIN包呢?我认为lpNumberOfBytesRecvd 也将设置为0,但我不确定。
【问题讨论】:
如果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。
WSARecv(),WSARecv()返回了0,WSAGetLastError()也返回了0!