【问题标题】:How to know when the socket has received a FIN packet when using WSARecv() and IOCP?使用 WSARecv() 和 IOCP 时如何知道套接字何时收到了 FIN 数据包?
【发布时间】:2015-03-06 12:41:46
【问题描述】:

当使用阻塞套接字和recv()函数时,当套接字收到一个FIN包时,recv()会返回0

但是,在使用WSARecv()和IOCP时,如何知道socket何时收到了一个FIN包呢?我认为lpNumberOfBytesRecvd 也将设置为0,但我不确定。

【问题讨论】:

    标签: c++ sockets iocp


    【解决方案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()返回了0WSAGetLastError()也返回了0
    • @RemyLebeau FIN 就像 TCP 数据段一样接受确认和重传。
    猜你喜欢
    • 1970-01-01
    • 2022-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-04
    • 2011-05-07
    • 1970-01-01
    相关资源
    最近更新 更多