Python套接字没有正确关闭连接

时间:2011-02-18 11:02:35

标签: python windows linux sockets networking

我是socket编程的新手,遇到了一个令人费解的问题:

我有一个Windows程序,我无法改变(专有软件)但尝试使用tcp套接字连接到特定的ip和端口。

在我的linux盒子上,我写了一个小的python脚本来为win prog服务套接字。这工作正常,直到我杀死我在Linux上的编程。初始服务器套接字未按指定关闭,我无法重新启动程序,直到套接字被垃圾回收。

如果我尝试使用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,但它仍然有用。

2 个答案:

答案 0 :(得分:29)

您遇到连接套接字的TIME_WAIT状态。即使你关闭了你的插座,它仍然会在几分钟内产生挥之不去的后果。 UNIX guide socket FAQ中解释了原因,以及可以设置为禁用行为的套接字标志(SO_REUSEADDR)。

简而言之,

server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

答案 1 :(得分:2)

尝试添加import sys并使用sys.exit()终止您的应用。套接字保持保留状态,直到系统确信应用程序已关闭。您可以使用sys.exit()

明确说明这一点

[编辑]哦,好的。我自己对插座很新。所以你说这个序列不安全吗?我想不出任何其他方式去做。您必须使用某种技术在某个时刻关闭您的应用程序,对吧?那怎么做呢?

server.shutdown(socket.SHUT_RDWR) 
server.close()
sys.exit()