Python套接字无法正确关闭连接

发布于 2024-10-18 04:24:40 字数 1191 浏览 1 评论 0原文

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

我有一个无法更改的 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 套接字?我是否错过了有关套接字的一些基本知识?

谢谢!

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

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

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.

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.

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

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.

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

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

Thanks!

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

染柒℉ 2024-10-25 04:24:40

您正在经历已连接套接字的 TIME_WAIT 状态。即使您已经关闭了套接字,它仍然会在几分钟内产生挥之不去的后果。 UNIX 引导套接字常见问题解答

简而言之,

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

You are experiencing the TIME_WAIT state 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.

In short,

server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(...)
...
失而复得 2024-10-25 04:24:40

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

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

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

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

[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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文