【问题标题】:Berkley sockets shutdown function, how important?Berkley sockets的shutdown函数,有多重要?
【发布时间】:2010-11-03 22:55:35
【问题描述】:

作为背景,我有一个通过 IP 与第三方服务器通信的嵌入式设备。第三方服务器中的代码不太可能更改。在最近的一个版本中,我将 ip disconnect 函数更改为在调用 close() 之前调用 shutdown()(之前它只是调用了 close())。如果发生某些中断,嵌入式设备会在未完成通信会话的情况下断开连接。当这种情况发生在会话中的错误点时,服务器现在正在生成一个跟踪文件,由于各种原因,该文件对客户来说是不可接受的。这仅在调用 shutdown 时发生,服务器将此视为发送失败错误(并生成跟踪文件),而将更突然的 close() 视为不需要跟踪的另一端断开连接错误。

所以显而易见的解决方案是停止调用关机。 Barnes 先生在question 中的回答很好地描述了这两个函数,但是,如果您知道只有一个进程连接到特定套接字,那么是否有任何理由在关闭之前使用关闭?

谢谢, 帕特里克

【问题讨论】:

  • 您在嵌入式设备和第三方服务器上使用什么 TCP 堆栈?并非所有 TCP 堆栈都具有相同的行为 w.r.t。 shutdownclose。另外,您是否设置了SO_LINGER 选项?
  • 如何识别tcp栈?我们确实在最后使用 SO_LINGER。
  • 首先让我们知道涉及哪些操作系统(或库)和版本。

标签: tcp berkeley-sockets


【解决方案1】:

在我看来,“突然断开连接”已成为您通信协议的一部分,这不是一件好事。如果客户端在“发生某些中断”之后运行很长时间来决定是否使用shutdown()close() 并影响另一端看到的内容,那么最好更新您的协议以可靠地提供“此会话是中止消息。”

也就是说,听起来好像这个系统(即所有的交互软件)已经(在服务器上)严重冻结了一点,以至于这种变化永远不会发生。可能你想要做的,而不是弄清楚问题到底是什么,是让经理签署一个快速而肮脏的“只需使用close()”解决方案,在向他解释你并不是真的确定这可能会产生什么其他影响,但以前的情况似乎确实运行良好。 (自从您进行更改后,您没有注意到任何其他错误消失,是吗?)

决定是否进行潜在昂贵的搜索以了解此处实际发生的情况,以及与另一端负责维护该软件的某个组织进行潜在的昂贵(政治上,如果不是财务上),这实际上是一项管理决策,不是技术问题,但要正确制作,需要了解技术风险。

【讨论】:

  • 客户端在中断发生后没有运行,唯一的问题是它错误地将优雅关闭解释为需要跟踪的错误,而很高兴接受直接关闭。无论哪种方式,它都可以毫无问题地继续工作,只是跟踪文件的这种副作用......无论如何都是好建议,有时你只需要让事情按照客户的意愿工作,谢谢。
【解决方案2】:

如果你知道只有一个进程 连接到特定的套接字,是 有任何理由使用关机 收盘前?

不,没有。与那里的许多文档相反。如果 FIN/ACK 尚未发送,Close 会关闭握手。

编辑:但这并不是说关机没有它的用​​途:当然有。如果您想停止发送,并希望接收者知道这一点,但又想继续接收,那就是它的目的。另一个用途是几乎解决了两军问题并获得同步关闭:如果您读取 EOS,则发送关闭并关闭;如果要启动关闭,请发送关闭并读取直到 EOS,然后关闭。如果您的应用程序协议正确,则后一步不应读取任何数据,并且两端的关闭将是相当同时的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2016-07-04
    • 2014-08-04
    相关资源
    最近更新 更多