Linux Python套接字未正确关闭连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5040491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:54:17  来源:igfitidea点击:

Python socket doesn't close connection properly

pythonwindowslinuxsocketsnetworking

提问by BandGap

I am new to socket programming and ran into a puzzling problem:

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

I have a windows program which I cannot alter (proprietary software) but which tries to connect to a specific ip and port with a tcp socket.

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

On my linux box I wrote a little python script to serve the socket to the win prog. This works fine until I kill my prog on linux. The initial server socket doesn't close as specified and I cannot restart my program until the socket is garbage collected.

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

If I try the same with a linux socket (in a seperate python script) I have no problems.

如果我对 linux 套接字(在单独的 python 脚本中)尝试同样的操作,我没有问题。

Here is a minimal code example:

这是一个最小的代码示例:

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()

If I kill this with Ctrl-C it exits normally. But upon restarting the script I get a socket.error stating the address is already in use. After a minute or so the program works again.

如果我用 Ctrl-C 杀死它,它会正常退出。但是在重新启动脚本时,我收到一个 socket.error,说明地址已被使用。大约一分钟后,程序再次运行。

I also tried a shutdown before the close (aka conn.shutdown(2) and server.shutdown...) but that has no effect.

我还尝试在关闭之前关闭(又名 conn.shutdown(2) 和 server.shutdown...),但这没有效果。

Is there a better 'right' way to close a windows socket? Do I miss something fundamental about sockets in general?

有没有更好的“正确”方法来关闭 Windows 套接字?我是否错过了有关套接字的基本知识?

Thanks!

谢谢!

edit: I think I just saw the answer here: what is the correct way to close a socket in python 2.6?

编辑:我想我刚刚在这里看到了答案: 在 python 2.6 中关闭套接字的正确方法是什么?

Although I'm using python 2.5 it might still work.

虽然我使用的是 python 2.5,但它可能仍然有效。

采纳答案by Jean-Paul Calderone

You are experiencing the TIME_WAITstate of connected sockets. Even though you've closed your socket, it still has lingering consequences for a couple minutes. The reasons for this, as well as a socket flag you can set to disable the behavior (SO_REUSEADDR), are explained in the UNIX guide socket FAQ.

您正在体验TIME_WAIT连接套接字的状态。即使您已经关闭了套接字,它仍然会在几分钟内产生挥之不去的后果。其原因以及您可以设置以禁用该行为 (SO_REUSEADDR) 的套接字标志在UNIX 指南套接字常见问题解答中进行了解释。

In short,

简而言之,

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

回答by Alan

Try adding import sys and terminating your app with sys.exit(). The socket stays reserved until the system is satisfied that the application is closed. You can be explicit about that with sys.exit()

尝试添加 import sys 并使用 sys.exit() 终止您的应用程序。套接字保持保留,直到系统对应用程序关闭感到满意为止。您可以使用 sys.exit() 明确说明这一点

[edit]Oh, ok. I am pretty new to sockets myself. So you are saying that this sequence is not safe? I cant imagine any other way to do it. You have to close your app at some point, with some technique, right? How is it correctly done then?

[编辑]哦,好的。我自己对套接字很陌生。所以你是说这个序列不安全?我无法想象任何其他方式来做到这一点。您必须在某个时候使用某种技术关闭您的应用程序,对吗?那它是如何正确完成的呢?

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