在已经被客户端删除的TCP套接字上调用send()会导致内存访问冲突,就像我运行我制作的服务器应用程序然后用来自浏览器的请求轰炸它一样,它会崩溃在服务约7至11个请求之后。具体来说,它接受连接,然后坐了大约10秒左右,然后Windows抛出“此程序已停止工作...”消息。如果我删除send()调用,就不会发生这样的崩溃,导致我认为Microsoft的send()不能安全地处理从另一端关闭的套接字。
我知道有多种方法可以检查套接字是否实际上已经关闭,但我不想检查然后发送,因为客户端仍然有可能在检查和发送之间切断。
编辑:我在“类似问题”框中注意到close() socket directly after send(): unsafe?,虽然它不太适合我的情况,但我现在想知道在发送后是否快速调用close() ()可能是导致问题的原因。
如果是这种情况,那么检查然后关闭的解决方案将工作,因为它没有上述含义。但是,我不知道如何检查closesocket()是否安全。
编辑:我也可以通过一种方法来检测send()实际上已经破坏并阻止整个应用程序崩溃。
编辑:我想我最后会更新这个问题,考虑到我刚才发现这个问题,可能会有好奇的人绊倒这个问题。事实证明,该问题与send
函数或与套接字相关的任何其他内容无关。实际上,问题是我正在做的非常愚蠢:在无效指针(free
和垃圾数据地址等)上调用NULL
。几年前,我终于从我最初使用的一个非常过时的版本更新了我的编译器,我想这个过时的标准库实现是让我能够摆脱这种令人畏惧的实践,而且似乎是什么我认为send
的一个问题是副作用。
答案 0 :(得分:2)
我已经在WinSock中编程了十多年,并且从未见过或听说send()
在失败时抛出异常(事实上,没有Win32 API函数在失败时抛出异常)。如果套接字已关闭,则会报告相应的错误代码。所以你的代码中还有别的东西。也许传递给buf
参数的指针不指向有效的内存块,或者可能传递给len
参数的值超出buf
的范围。
答案 1 :(得分:2)
就像@RemyLebeau一样,我已经在Winsock编程了十多年,在我的情况下已经超过两个几十年了,我也从未见过这个。
Microsoft的send()
处理发送到已被另一端关闭的连接,返回SOCKET_ERROR
( - 1),WSAGetLastError()
返回WSAECONNRESET
}。除非连接异常丢失(网络故障等),在这种情况下,WinSock不知道连接已经消失,并且send()
愉快地保持缓冲出站数据,直到套接字的缓冲区填满,或者套接字在内部超时,然后报告失败。
您所引用的发送/关闭问题不包含有关内存访问错误的任何内容,并且无论如何在 close()
之后调用send()
可能导致先前错误send()
行为不端,除非你设法让时间倒退。
您的代码中有错误。