【问题标题】:Can writes to a datagram socket ever raise SIGPIPE?写入数据报套接字是否会引发 SIGPIPE?
【发布时间】:2011-08-05 01:50:59
【问题描述】:

由于SIGPIPE,我正在处理一些需要安全防止杀死调用者的代码,但它正在执行的唯一套接字写入是数据报套接字(UDP 和 Unix 域数据报套接字)。我需要担心SIGPIPE 吗?我在套接字上使用 connect,但初步测试(在 Linux 上)表明,如果没有人在 Unix 域套接字上监听,我只会在发送时收到 ECONNREFUSED。不确定 UDP 会发生什么。

我可以用 hack 包起来以摆脱 SIGPIPE,但如果这不是问题,我宁愿节省开销并降低代码复杂性。

【问题讨论】:

  • 我会给你一个不好的答案。我想我之前在 Linux 系统启动时启动应用程序时已经看到过这种情况。我不能说它是否绝对是一个数据报套接字是潜在的问题,但据我所知,我们没有为该应用程序使用任何 TCP 套接字。只是一个测试用例供您考虑它是否适用于您。
  • 我想我可能只是安排使用sendto 而不是write,这样我就可以传递禁用SIGPIPE 的标志。

标签: c sockets posix datagram sigpipe


【解决方案1】:

答案在send的规范中:

[EPIPE] 套接字关闭写入,或套接字处于连接模式,不再连接。在后一种情况下,如果套接字是 SOCK_STREAM 或 SOCK_SEQPACKET 类型且未设置 MSG_NOSIGNAL 标志,则会向调用线程生成 SIGPIPE 信号。

http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html

因此,不,写入数据报套接字不会产生SIGPIPEEPIPE 错误。

【讨论】:

  • 难道上面的文字实际上不是说如果“套接字因写入而关闭”(无论这意味着什么),您可以在 UDP 中获取它吗?
  • @T.E.D.:也许(如果 shutdown-for-write 适用于数据报套接字),但如果没有程序员的意图或错误,这种情况不会发生。不是同行造成的。
【解决方案2】:

公开组是一回事,Apple 是另一回事。 正如我最近的一些崩溃日志所揭示的那样,当写入死的 UDP 套接字时,绝对有可能在 iOS 上获得 SIGPIPE。 iOS 倾向于在应用程序处于后台时关闭 UDP 套接字,写入这些套接字会弹出 SIGPIPE。
来自我的崩溃日志(由 testflightapp 提供):

异常最新的受害者事件
SIGPIPE
2 libsystem_c.dylib 0x32df47ec _sigtramp + 48
3 即时通话 0x0005b10e -[IPRSNetDatagramSocket send:size:to:] (iprs_iphone_net.m:671)...

不记得在 Linux、Solaris 或 Windows 上发生过这种情况 - 尽管我从未尝试关闭套接字然后对其进行写入。

【讨论】:

  • 关闭一个套接字然后写入它不会给SIGPIPEEPIPE;它会给EBADF。 iOS 必须将套接字置于某种特殊的非标准模式才能导致SIGPIPE。在任何情况下,我的问题都被标记为 POSIX,因为我正在寻找标准行为,但您的回答也很丰富。
【解决方案3】:

根据我的 Debian 盒子上的man 2 write

EPIPE:fd 连接到读取端已关闭的管道或套接字。当这种情况发生时,写入过程也会收到一个 SIGPIPE 信号。 (因此,写 仅当程序捕获、阻塞或忽略此信号时才能看到返回值。)

似乎在写入套接字时可以获得 SIGPIPE,但尚不清楚它是否会专门针对 UDP 套接字发生。

【讨论】:

  • send 的手册页更具体一些,但不像 POSIX 所说的 send 那样清楚..
  • 确实,@R ...我在您发布后几秒钟就投了赞成票。我只是想让我的帖子顺利进行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 2017-12-25
相关资源
最近更新 更多