【问题标题】:winsock2: send() fails if socket is dead [not really]winsock2:如果套接字已死,则 send() 失败 [不是真的]
【发布时间】:2014-09-10 01:58:29
【问题描述】:

在已被客户端丢弃的 TCP 套接字上调用 send() 会导致内存访问冲突,因为当我运行我创建的服务器应用程序然后用来自浏览器的请求轰炸它时,它会崩溃在服务了大约 7 到 11 个请求之后。具体来说,它接受连接,然后最多停留 10 秒左右,然后 Windows 抛出“该程序已停止工作......”消息。如果我删除 send() 调用,就不会发生这样的崩溃,这让我相信 Microsoft 的 send() 不能安全地处理从另一端关闭的套接字。

我知道有多种方法可以检查套接字是否实际上已关闭,但我不想检查然后发送,因为客户端仍有可能在检查和发送之间中断。


编辑:我在“类似问题”框中注意到close() socket directly after send(): unsafe?,虽然它不太适合我的情况,但我现在想知道是否在 send() 之后快速调用 close()可能是造成问题的原因。

如果是这种情况,涉及检查然后关闭 的解决方案会起作用,因为它没有上述含义。但是,我不知道如何检查 closesocket() 是否安全。


编辑:我也可以用一种方法来检测 send() 实际上已损坏并防止整个应用程序崩溃。


编辑:我想我终于要更新这个问题了,因为我不久前就发现了这个问题,可能会有好奇的人偶然发现这个问题。事实证明,该问题与send 函数或与套接字相关的任何其他内容无关。事实上,问题出在我正在做的一件非常愚蠢的事情上:在无效指针上调用freeNULL 和类似的垃圾数据地址)。几年前,我终于从我最初使用的一个非常过时的版本更新了我的编译器,我想非常过时的标准库实现让我能够摆脱这种令人畏惧的做法,似乎什么我认为send 的问题是它的副作用。

【问题讨论】:

    标签: tcp send winsock2


    【解决方案1】:

    我已经在 WinSock 中编程十多年了,从未见过或听说过 send() 在失败时抛出异常(事实上,没有 Win32 API 函数在失败时抛出异常)。如果套接字已关闭,则会报告相应的错误代码。因此,您的代码中发生了其他事情。可能您传递给buf 参数的指针未指向有效的内存块,或者您传递给len 参数的值可能超出了buf 的范围。

    【讨论】:

    • 感谢您的回复,如果我发现之前尝试修复它时遗漏了什么,我将再次查看 send() 的参数并发布。
    【解决方案2】:

    和@RemyLebeau 一样,我在Winsock 中编程已经有十多年了,就我而言,已经两个 几十年了,我也从未见过这种情况。

    Microsoft 的 send() 通过返回 SOCKET_ERROR (-1) 和 WSAGetLastError() 返回 WSAECONNRESET 来处理发送到已被另一端关闭的连接。除非连接异常丢失(网络故障等),在这种情况下,WinSock 不知道连接已丢失,并且send() 愉快地继续缓冲出站数据,直到套接字的缓冲区填满,或者套接字在内部超时,因此失败是然后报告。

    您提到的发送/关闭问题不包含任何有关内存访问错误的内容,并且无论如何调用close() 之后 send() 不可能导致先前的send() 行为不端,除非你设法让时间倒流。

    您的代码中某处存在错误。

    【讨论】:

    • 已经好多年了——不是因为我花了那么长时间才弄明白(感谢上帝)——而是因为我忘记了我曾问过这个问题。
    • 但事实证明,你是对的:这个问题与套接字完全无关,而是我正在做的一件非常愚蠢的事情的症状,freeing 无效地址。
    猜你喜欢
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 2015-12-26
    • 2014-06-19
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    相关资源
    最近更新 更多