Berkley套接字的关闭功能有多重要?
作为背景,我有一个嵌入式设备,可以通过 IP 与第三方服务器通信。 第三方服务器中的代码不太可能更改。 在最近的版本中,我将 ip disconnect 函数更改为在调用 close() 之前调用 shutdown()(之前它只是调用 close())。 如果发生某些中断,嵌入式设备会在未完成通信会话的情况下断开连接。 当这种情况发生在会话中的错误点时,服务器现在会生成一个跟踪文件,由于各种原因,该文件是客户无法接受的。 这种情况仅在调用 shutdown 时发生,服务器将此视为发送失败错误(并生成跟踪文件),同时将更突然的 close() 视为不需要跟踪的另一端断开连接错误。
所以显而易见的解决方案是停止调用 shutdown。 巴恩斯先生在这个问题中的回答很好地描述了这两个函数,但是,如果您知道只有一个进程附加到特定套接字,是否有任何理由在关闭之前使用 shutdown ?
谢谢, 帕特里克
as background I've got an embedded device that talks to a third party server over IP. The code in the third party server is unlikely to change. In a recent release I changed the ip disconnect function to call shutdown() before calling close() (previously it had just called close()). The embedded device disconnects without completing a comms session if certain interrupts occur. When this happens at the wrong point in a session the server is now producing a trace file which, for various reasons, is not acceptable to the customer. This only happens when shutdown is called, the server treats this as a failed to send error (and produces a trace file) while it treats the more abrupt close() as an other end disconnected error which doesn't need tracing.
So the obvious solution is to stop calling shutdown. Mr Barnes' answer in this question gives a good description of the two functions but, if you know that only one process is attached to a particular socket, is there any reason to use shutdown before a close?
Thanks,
Patrick
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在我看来,“突然断开”似乎已经成为你的通信协议的一部分,这不是一件好事。 如果客户端在“发生某些中断”后运行很长时间来决定是否使用
shutdown()
或close()
并影响另一端看到的内容,最好更新您的协议以可靠地传递“此会话已中止消息”。也就是说,听起来好像这个系统(即所有交互软件)已经(在服务器上)冻结得足够严重,以至于这种变化永远不会发生。 也许您想要做的不是弄清楚问题到底是什么,而是让经理在解释后签署一个快速而肮脏的“只需使用
close()
”解决方案他说你不太确定这还会产生什么其他影响,但之前事情似乎确实运行良好。 (自从进行更改后,您没有注意到任何其他错误消失了,不是吗?)决定是否进行可能昂贵的搜索,以了解这里到底发生了什么,以及潜在的昂贵(政治上,如果不是经济上)另一端负责维护该软件的某个组织实际上是一项管理决策,而不是技术决策,尽管要正确做出决策,需要了解技术风险。
It sounds to me as if "abrupt disconnection" has become part of your communications protocol, which is not a good thing. If the client is running for long after "certain interrupts occur" to decide whether or not to use
shutdown()
orclose()
and have that influence what the other end sees, it would be better to update your protocol to reliably deliver a "this session is aborted message."That said, it's sounding as if this system (i.e., all of the interacting software) has gotten one bit (on the server) frozen badly enough that this sort of change is never going to happen. Probably what you want to do, rather than figuring out what the problem really is, is get a manager to sign off on a quick-and-dirty "just use
close()
" solution, after explaining to him that you're not really sure what other effects this could have, but things did seem to run ok that way before. (You haven't noticed any other bugs disappear since you made that change, have you?)Deciding whether to get into a potentially expensive search to see what's really going on here, along with a potentially expensive (politically, if not financially) with some organization on the other end responsible for maintaining that software is really a management decision, not a technical one, though to be made properly it needs to be informed by the technical risks.
不,没有。 与很多文档相反。 如果尚未发送,则 Close 执行 FIN/ACK 关闭握手。
编辑:但这并不是说关闭没有它的用处:当然有。 如果您想停止发送,并希望接收者知道这一点,但又想继续接收,那就是它的用途。 另一个用途是几乎解决两军问题并获得同步关闭:如果您读取EOS,则发送关闭并关闭; 如果您想启动关闭,请发送关闭并读取直到 EOS,然后关闭。 如果您的应用程序协议正确,则后一步不应读取任何数据,并且两端的关闭将相当同步。
No there isn't. Contrary to a lot of documentation out there. Close does the FIN/ACK close handshake if it hasn't been sent already.
EDIT: however that's not to say that shutdown doesn't have its uses: of course it does. If you want to stop sending, and want the receiver to know that, but want to keep receiving, that's what it's for. Another use is to almost solve the two-army problem and get synchronized closes: if you read EOS, send a shutdown and close; if you want to initiate the close, send a shutdown and read until EOS and then close. If your application protocol is correct the latter step shouldn't read any data, and the closes at both ends will have been fairly simultaneous.