Python套接字没有正确关闭连接
Posted
技术标签:
【中文标题】Python套接字没有正确关闭连接【英文标题】:Python socket doesn't close connection properly 【发布时间】:2011-06-29 18:08:32 【问题描述】:我是套接字编程的新手,遇到了一个令人费解的问题:
我有一个无法更改的 Windows 程序(专有软件),但它尝试使用 tcp 套接字连接到特定的 IP 和端口。
在我的 linux 机器上,我编写了一个小的 python 脚本来为 win prog 提供套接字。这工作正常,直到我在 linux 上杀死我的 prog。初始服务器套接字未按指定关闭,在套接字被垃圾收集之前我无法重新启动程序。
如果我对 linux 套接字(在单独的 python 脚本中)尝试相同的操作,我没有问题。
这是一个最小的代码示例:
import socket
server = socket.socket()
server.bind(('192.168.0.111', 50001))
server.listen(1)
conn, addr = server.accept()
print 'Connection established'
running = True
while running:
try:
data = conn.recv(4096)
except KeyboardInterrupt:
conn.close()
running = False
else:
if data:
print data
else:
conn.close()
running = False
server.close()
如果我用 Ctrl-C 杀死它,它会正常退出。但是在重新启动脚本后,我得到一个 socket.error 说明该地址已在使用中。大约一分钟后,程序再次运行。
我也尝试在关闭前关闭(又名 conn.shutdown(2) 和 server.shutdown...),但没有效果。
有没有更好的“正确”方法来关闭 Windows 套接字?我是否错过了有关套接字的一些基本知识?
谢谢!
编辑:我想我刚刚在这里看到了答案: what is the correct way to close a socket in python 2.6?
虽然我使用的是 python 2.5,但它可能仍然可以工作。
【问题讨论】:
echo "disconnect" | nc 192.168.1.12 58888 -w 1
- 从客户端你可以超时 1 秒,让服务器有自己的超时时间
【参考方案1】:
您正在经历连接套接字的TIME_WAIT
状态。即使您关闭了套接字,它仍然会在几分钟内产生挥之不去的后果。 UNIX guide socket FAQ 中解释了造成这种情况的原因,以及您可以设置以禁用该行为 (SO_REUSEADDR) 的套接字标志。
总之,
server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(...)
...
【讨论】:
已连接个套接字的TIME_WAIT状态。 添加了一些上下文【参考方案2】:尝试添加 import sys 并使用 sys.exit() 终止您的应用。套接字保持保留,直到系统对应用程序关闭感到满意。您可以使用 sys.exit() 明确说明这一点
[编辑]哦,好的。我自己对套接字很陌生。所以你是说这个序列不安全?我无法想象任何其他方式来做到这一点。你必须在某个时候通过一些技巧关闭你的应用程序,对吧?那么它是如何正确完成的呢?
server.shutdown(socket.SHUT_RDWR)
server.close()
sys.exit()
【讨论】:
我实际上也想到了这一点,并将其写入我的脚本中。如果这对套接字关闭之前的延迟有影响,则可以忽略不计。 我不推荐使用 sys.exit()。您最终可能会遇到挂起的套接字,这在 Unix 上非常罕见,在 Windows 上并不罕见。如果你在 Windows 上挂了一个套接字,你必须重新启动才能修复。 sys.exit() 与退出 Python 进程的任何其他方式没有任何不同。因此,您的建议归结为“如果您创建了任何套接字,请不要退出”,这有点不切实际。如果您的程序永远不会退出,您可能也必须重新启动。 ;) 一般来说,Windows 是相当脆弱的,防火墙和防病毒软件之类的东西会使它更加脆弱。但是,退出一个打开了套接字的进程可能基本上一直都是安全的,如果不是这样,你的系统就会出现很多问题,以至于你不会真正注意到一个有问题的 Python 程序。以上是关于Python套接字没有正确关闭连接的主要内容,如果未能解决你的问题,请参考以下文章