当套接字关闭时出现“Broken pipe”错误

7

我在Linux系统中有一个服务器/客户端应用程序。如果客户端尝试发送请求时,服务器没有启动,我会收到SIGPIPE信号并导致应用程序终止。

在尝试写入之前,我该如何检查socket上的服务器是否可用?

还值得注意的是,我不想捕获SIGPIPE,因为客户端实际上是由许多应用程序共享的共享对象的一部分,这些应用程序可能已经定义了自己的信号处理方法。

谢谢


你可以禁止本地Unix套接字。对于这种类型的套接字,只会生成SIGPIPE信号。但这可能会严重影响性能。 - Šimon Tóth
另一个SO帖子可能会有用:https://dev59.com/RHVD5IYBdhLWcg3wDHDm - ukhardy
2
你也会在inet流套接字中收到SIGPIPE。 - Erik
把它“out-of-band”做会更容易,比如说?例如,使用/var/run/server.pid文件或类似的东西,客户端可以检查以确定服务器是否在运行。 - Ilkka
1
@Ilkka:你只会引入竞争条件,使错误更加罕见。 - Erik
1
我建议将问题标题更改为更具描述性的内容。也许是“如何处理来自库的SIGPIPE而不干扰主程序”。 - Zan Lynx
2个回答

7
MSG_NOSIGNAL 作为标志传递给 send()

MSG_NOSIGNAL不具有可移植性。 - ukhardy
@ukhardy:OP在标签中提到了Linux。 - Erik
这绝对是 Linux 专用的。我会试着操作一下并告诉你结果。感谢你的反馈。 - steveo225
谢谢,这正是我所需要的;现在send在失败时返回-1而不是SIGPIPE。有趣的是,在send的man页面中我没有找到关于MSG_NOSIGNAL的提及。 - steveo225

0

这篇由kroki撰写的文章描述了一种看起来不错的方法。

总结如下:

  • 检查SIGPIPE是否挂起。将其记录在一个变量中。如果在我们开始之前它已经挂起,那么其他人阻止了SIGPIPE。在这种情况下,跳过下面的所有信号内容,直接执行写操作。
  • sigblock SIGPIPE。
  • 进行写操作。
  • 检查SIGPIPE是否挂起。
  • 如果它挂起,则使用零超时等待它。
  • 取消阻塞SIGPIPE。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接