我想编写一个接受tcp连接的服务器但我不想在调用socket.accept()
时阻塞主线程,所以我想将网络放在另一个线程中。我已经看到没有办法在Python中断一个线程,现在我想知道如何正确地停止socket.accept()
调用。
我想要的解决方案类似于Java,例如:
class TcpServer:
def waitForConnection():
try:
conn, addr = socket.accept()
except ThreadInterrupt:
# Close server ...
不幸的是,这个“ThreadInterrupt”不存在。那么,我该如何实现这种行为呢?提前感谢每个提示。
答案 0 :(得分:3)
您可以将套接字设置为非阻塞操作,并等待旧的select
调用,以便为accept
做好准备(当它变为可读时
第一次)。附加值是您可以侦听另一个文件
描述符,例如管道,这样您就可以进行特权通信
使用您的线程进行通道,您可以随时退出该线程:
import select
import socket
import os
class TcpServer:
def __init__(self, ...):
self.r_channel, self.w_channel = os.pipe()
self.socket = ...
def waitForConnection(self):
rfds, _, _ = select.select([self.socket.fileno(), self.r_channel],[],[])
if self.r_channel in rfds:
# close server
...
self.socket.accept() # this won't block
# if you want to interrupt waitForConnection, from main thread:
os.write(tcp_server_object.w_channel, '!') # write something, just to wake up the select call
答案 1 :(得分:1)
您可以使用settimeout
并通过某个变量(我的示例中为CONDITION
)向线程发出信号:
CONDITION = False
s.settimeout(1.0)
while True:
try:
if CONDITION: break
conn, addr = s.accept()
break
except socket.timeout as e:
pass
在另一个帖子中,你必须将CONDITION
设置为True,然后在CONDITION
阻止后测试while
。