TCP 发送未返回导致进程崩溃

发布于 2024-08-02 20:01:53 字数 239 浏览 10 评论 0原文

如果 tcp 服务器和客户端已连接,我想确定客户端何时不再连接。我想我可以简单地通过尝试向客户端发送消息来做到这一点,一旦 send() 返回 -1,我就可以拆除套接字。这个实现可以在 Windows 上找到,但是当我尝试在带有 BSD 套接字的 Linux 上执行此操作时,如果客户端不再连接,对服务器端应用程序上的 send() 的调用会导致我的服务器应用程序崩溃。它甚至不返回 -1...只是终止程序。

请解释为什么会发生这种情况。提前致谢!

If a tcp server and client are connected, I'd like to determine when the client is no longer connected. I thought I can simply do this by attempting to send a message to the client and once send() returns with a -1, I can then tear down the socket. This implementation works find on Windows but the minute I try doing this on Linux with BSD sockets, the call to send() on the server side app causes my server app to crash if the client is no longer connected. It doesn't even return a -1...just terminates the program.

Please explain why this is happening. Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嗳卜坏 2024-08-09 20:01:53

这是由 SIGPIPE 信号引起的。请参阅send(2)

如果发生以下情况,send() 函数将失败:
[EPIPE]
套接字因写入而关闭,或者套接字处于连接模式并且不再连接。在后一种情况下,如果套接字的类型为 SOCK_STREAM 或 SOCK_SEQPACKET 并且未设置 MSG_NOSIGNAL 标志,则会向调用线程生成 SIGPIPE 信号。

您可以通过在 send() 调用中使用 MSG_NOSIGNAL 标志来避免这种情况,或者通过使用 signal(SIGPIPE) 忽略 SIGPIPE 信号, SIG_IGN) 在程序的开头。在这种情况下,send() 函数将返回 -1 并将 errno 设置为 EPIPE

This is caused by the SIGPIPE signal. See send(2):

The send() function shall fail if:
[EPIPE]
The socket is shut down for writing, or the socket is connection-mode and is no longer connected. In the latter case, and if the socket is of type SOCK_STREAM or SOCK_SEQPACKET and the MSG_NOSIGNAL flag is not set, the SIGPIPE signal is generated to the calling thread.

You can avoid this by using the MSG_NOSIGNAL flag on the send() call, or by ignoring the SIGPIPE signal with signal(SIGPIPE, SIG_IGN) at the beginning of your program. Then the send() function will return -1 and set errno to EPIPE in this situation.

染年凉城似染瑾 2024-08-09 20:01:53

您需要忽略 SIGPIPE 信号。如果套接字上发生写入错误,您的进程将收到 SIGPIPE,并且该信号的默认行为是终止您的进程。
在 *nix 上编写您通常需要的网络代码:

signal(SIGPIPE,SIG_IGN);

You need to ignore the SIGPIPE signal. If a write error happens on a socket, your process with get SIGPIPE, and the default behavior of that signal is to kill your process.
Writing networking code on *nix you usually want:

signal(SIGPIPE,SIG_IGN);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文