我在尝试了解网络通信套接字时遇到问题。我做了一个简单的线程,它监听连接并创建连接客户端的进程,我的问题是我无法正常连接线程,因为我还没有找到取消socket.accept()的方法 - 调用当我想退出该计划时。
我的代码看起来像这样;
class ServerThread( threading.Thread ):
def __init__(self, queue, host, port):
threading.Thread.__init__(self)
self.queue = queue
self.running = True
self.hostname = host
self.port = port
def run(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind((self.hostname, self.port))
self.socket.listen(1)
while self.running:
try:
conn, address = self.socket.accept()
process = Process(target=server_slave, args=(conn, address, self.queue))
process.daemon = True
process.start()
except socket.timeout:
pass
def stop(self):
self.running = False
self.socket.close()
我设法通过设置self.setDaemon(True)
并退出主程序,将所有内容交给大垃圾收集器来关闭程序 - 但这似乎是一个糟糕的解决方案。我也尝试为套接字设置超时,但这会导致获得[Errno 35] Resource temporarily unavailable
(无论实际超时,即使我将其设置为年......)。
我做错了什么?我是否以愚蠢的方式设计了线程,或者我错过了接受连接的内容?
答案 0 :(得分:11)
让线程关闭的一种方法似乎是建立与套接字的连接,从而继续完成线程。
def stop(self):
self.running = False
socket.socket(socket.AF_INET,
socket.SOCK_STREAM).connect( (self.hostname, self.port))
self.socket.close()
这样可行,但感觉可能不是最佳......
答案 1 :(得分:1)
允许退出程序的脏解决方案是使用os._exit(0)
。
def stop(self):
self.socket.close()
os._exit(0)
请注意sys.exit
在尝试彻底退出/释放资源时不起作用/阻止。但是os._exit
是最低级别的方式,它起作用,当没有别的时候。
操作系统本身将释放资源(在任何现代系统上),就像在C程序中执行exit
一样。
答案 2 :(得分:0)
在大多数情况下,一旦接受连接,您将打开一个新线程或进程。要关闭连接,请中断while循环。垃圾收集将删除线程或进程,但加入将确保没有留下任何东西。
持久套接字在用户关闭或超时时关闭。非持久性,如静态网页,在发送信息后将关闭。
这是Python中持久套接字服务器的一个很好的例子。它使用多处理,这意味着它可以跨多个核心运行以进行CPU绑定任务。通常称为多线程。
import socket
import multiprocessing
def run():
host = '000.000.000.000'
port = 1212
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', port))
sock.listen(3)
while True:
p = multiprocessing.Process(target=worker, args=sock.accept()).start()
def worker(conn, addr):
while True:
if data == '':
#remote connection closed
break
if len(dataList) > 2:
# do stuff
print 'This code is untested'
run()
答案 3 :(得分:0)
执行此操作的最佳方法是拥有一个与您的连接线程无关的侦听线程,并为其提供合理的长度超时。超时时,请检查该线程是否应该关闭,否则请再次循环并返回监听。
def tcp_listen_handle(self, port=23, connects=5, timeout=2):
"""This is running in its own thread."""
sock = socket.socket()
sock.settimeout(timeout)
sock.bind(('', port))
sock.listen(connects) # We accept more than one connection.
while self.keep_running_the_listening_thread():
connection = None
addr = None
try:
connection, addr = sock.accept()
print("Socket Connected: %s" % str(addr))
# makes a thread deals with that stuff. We only do listening.
self.handle_tcp_connection_in_another_thread(connection, addr)
except socket.timeout:
pass
except OSError:
# Some other error.
print("Socket was killed: %s" % str(addr))
if connection is not None:
connection.close()
sock.close()
唯一要做的就是监听,超时,检查是否应该在超时期间终止并返回监听。一般的经验法则是,线程应该检查是否应该死掉,并尽自己最大的努力做到这一点。而且,如果您不想让2秒命中超时,请等待线程取消阻塞并检查。您可以自己连接它。
答案 4 :(得分:-1)
部分测试的解决方案
self.socket.settimeout(0.1)
放在while
conn.settimeout(None)
accept
醇>