作为背景我有一个嵌入式设备通过IP与第三方服务器通信。第三方服务器中的代码不太可能更改。在最近的版本中,我更改了ip disconnect函数,在调用close()之前调用shutdown()(之前它刚刚调用了close())。如果发生某些中断,嵌入式设备将断开连接而不完成通信会话。当这发生在会话中的错误点时,服务器现在正在生成跟踪文件,由于各种原因,该文件对于客户来说是不可接受的。这只发生在调用shutdown时,服务器将其视为发送失败错误(并生成跟踪文件),同时将更突然的close()视为另一端断开连接错误,不需要跟踪。
所以显而易见的解决方案是停止调用shutdown。 Barnes先生在这个question中给出的回答很好地描述了这两个函数,但是,如果你知道只有一个进程附加到一个特定的套接字,那么有什么理由在关闭之前使用shutdown吗?
谢谢, 帕特里克
答案 0 :(得分:4)
听起来好像“突然断开连接”已成为您通信协议的一部分,这不是一件好事。如果客户端在“发生某些中断”后运行很长时间以决定是否使用shutdown()
或close()
并且影响另一端看到的内容,那么最好将协议更新为可靠地传递“此会话被中止的消息。”
也就是说,听起来好像这个系统(即所有交互软件)已经得到了一点(在服务器上)冻结得足够严重,以至于这种变化永远不会发生。可能你想做的事情,而不是弄清楚问题究竟是什么,是让经理在向他解释你是一个快速而肮脏的“只使用close()
”解决方案时签字不确定这可能会产生什么其他影响,但事情确实似乎以前那样运行。 (你没有发现任何其他错误消失,因为你做了那个改变,对吗?)
决定是否进入潜在的昂贵搜索,看看这里真正发生了什么,以及潜在的昂贵(政治上,如果不是经济上)与另一端负责维护该软件的组织实际上是一个管理决策,虽然要做得恰到好处,但需要了解技术风险。
答案 1 :(得分:1)
如果您知道只有一个流程 连接到特定插座,是 有任何理由使用关机 收盘前?
不,没有。与那里的许多文件相反。如果尚未发送FIN / ACK关闭握手,则关闭。
编辑:然而,这并不是说关闭没有用途:当然可以。如果你想停止发送,并希望接收者知道,但想继续接收,那就是它的用途。另一个用途是几乎解决双军问题并获得同步关闭:如果你阅读EOS,发送关机并关闭;如果要启动关闭,请发送关闭并读取直到EOS然后关闭。如果你的应用程序协议是正确的,后一步不应该读取任何数据,两端的关闭将是相当同时的。