Python socket在主线程中接受阻止退出

5 投票
5 回答
4810 浏览
提问于 2025-04-17 17:47

我正在用Python玩弄套接字(socket),主要是为了学习它们。不过,我遇到了一个让我很烦恼的问题:

import socket
soc = socket.socket(socket.AF_INET)
soc.bind(('localhost',8000))
soc.listen(0)
client = soc.accept()

当套接字在等待连接时,按下ctrl-c并不能退出这个程序。

我该怎么退出这个程序呢?

类似的问题在这两个问题中被讨论过,但那里的accept方法是在一个单独的线程中调用的,问题是如何让ctrl-c结束那个线程。而这里的accept方法是在主线程中调用的。

编辑:我在Win7 64位上运行的是Python 3.3.0。

5 个回答

1

我之前也遇到过同样的问题,找到了一种小方法,虽然可能不是最优雅的解决方案,但对我来说有效:

import socket
from select import select

#create an INET, STREAMing socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#bind the socket to localhost
serversocket.bind(('localhost', 8000))
While 1:
    serversocket.listen(5)
    ready, _, _ = select([serversocket], [], [], 1) #Timeout set to 1 seconds
    if ready:
        (clientsocket, address) = serversocket.accept()
        #Do something with client
    else:
        #Do nothing, just loop again

使用 select 的话,你可以在超时结束之前等待套接字的变化。正如我所说,这可能不是最干净的做法,但在超时结束时可以捕捉到 Ctrl-c。

注意移植性:在 Unix 系统上,select 可以同时用于套接字和文件。而在 Windows 系统上,select 只适用于套接字。

6

你可以试试按 CTRL + Break。这样应该能结束它。

4

我找不到用 ctrl-c 或其他方法来关闭这个应用程序,除了通过任务管理器来结束它,所以我写了一个变通的方法:

import socket,os
from threading import Thread

class socketListener(Thread):
    def run(self):
        soc = socket.socket(socket.AF_INET)
        soc.bind(('localhost',8000))
        soc.listen(0)
        client = soc.accept()

pid = os.getpid()
sl = socketListener()
sl.start()
input('Socket is listening, press any key to abort...')
os.kill(pid,9)

这个方法是在一个单独的线程中运行脚本,同时在主线程中等待用户按键。一旦用户按下任意键,整个应用程序就会被关闭。

撰写回答