程序关闭后套接字保持打开状态 (C++)
我目前正在编写一个小型服务器应用程序,我的问题是,当我关闭我的应用程序(或者更好的是,按 Eclipse 中的终止按钮)时,套接字有时会保持打开状态,因此当我下次执行我的应用程序时,绑定() 将失败并显示“地址已在使用中”。 当程序退出时如何正确关闭套接字? 我已经放入
close(mySocket);
了类析构函数,但这似乎没有改变任何东西。
I'm currently writing a small server application, and my problem is, that when I close my app (or better, press the terminate button in eclipse), the socket sometimes stays open, so when I execute my app the next time, bind() will fail with "Address already in use". How can I properly close my sockets when the program exits? I already put
close(mySocket);
in the class destructors, but that doesn't seem to change anything.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用 SO_REUSEADDR。
Use SO_REUSEADDR.
http://hea-www.harvard.edu/~fine/Tech/ addrinuse.html 应该可以回答您的很多问题。 我倾向于使用 SO_REUSEADDR 来解决这个问题。
http://hea-www.harvard.edu/~fine/Tech/addrinuse.html should answer a lot of your questions. I tend to use SO_REUSEADDR to work around that problem.
使用
netstat
确定您的端点所处的状态。我的猜测是它处于TIME_WAIT
状态并且未完全关闭。 对于 TCP 来说,这是正确的行为,并且存在的目的是允许可能仍在以太网中的杂散段到达并且不会导致问题。 TIME_WAIT 的持续时间类似于 2*MSL,即网络上分段最大生命周期的两倍,从而确保即使是重新传输的分段也能得到正确处理。正如其他人指出的那样,只要远端的端点每次都不同,
SO_REUSEADDR
就是您的朋友。 这是常见情况,但有时人们会做奇怪的事情,例如将客户端绑定到特定端口,在这种情况下,您仍然会得到EADDRINUSE
b/c TCP 将会话定义为 两个端点。Use
netstat
to figure out what state your endpoint is in. My guess is that it's in eitherTIME_WAIT
and not fully closed. This is correct behavior for TCP, and exists to allow stray segments that might still be out in the ether to arrive and not cause problems. The duration ofTIME_WAIT
is something like 2*MSL, i.e. twice the maximum lifetime of a segment on the network, thus insuring that even a segment that gets retransmitted gets properly handled.As others have pointed out,
SO_REUSEADDR
is your friend as long as the far side's endpoint is different each time. That's the common case, but sometimes people do weird things like bind a client to a specific port, and in that case you'll still end up with anEADDRINUSE
b/c TCP defines a session as both endpoints.您是否设置了
SO_REUSEADDR
选项? 从你说的情况来看,好像不是。Have you set the
SO_REUSEADDR
option? From what you're saying, it seems not.不要忘记检查 close 的返回值。 当套接字成功关闭时,它将返回0。 如果失败则返回-1。
Don't forget to check the return value of close. It will return 0 when the socket is successfully closed. It will return -1 if it failed.
您确定您的应用程序没有以某种方式仍在后台运行吗?
Are you sure your app is not somehow still running in the background?