[英]threaded TCP sockets with python
我是python编程和套接字的新手,所以我从http://docs.python.org/2/library/socketserver.html处的异步(线程)SocketServer示例开始。
ThreadingMixIn类的示例运行良好,但是对于专家我有两个问题:
每个新连接都会创建一个新线程,很好。 但是似乎线程永远不会终止,即使另一侧的连接随着线程数量的增加而关闭。
第二个问题是关于handle方法。 我尝试从客户端使用sendall发送2条连续消息,但是第二次发送失败...看来,实际上handle方法等待第一条消息,然后终止。 我必须添加“ while 1:”才能开始工作。
因此,总而言之,我感到这个示例是无用且不好的,因为它只是创建了一个只能接收一条消息的线程。 如果至少它会自行终止,但对我而言似乎并非如此……
感谢您的投入!
这是服务器的代码:
import threading
import SocketServer
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
cur_thread = threading.current_thread()
response = "{}: {}".format(cur_thread.name, data)
self.request.sendall(response)
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
server = ThreadedTCPServer(('localhost', 13009), ThreadedTCPRequestHandler)
# Start a thread with the server -- that thread will then start one
# more thread for each request
server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates
server_thread.daemon = True
server_thread.start()
print "Server loop running in thread:", server_thread.name
raw_input("Hit enter to stop the server")
server.shutdown()
和客户的代码:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 13009))
try:
sock.sendall('hello\n')
response = sock.recv(1024)
print "Received: {}".format(response)
# A second 'send' will generate an error on Windows.
# On Mac, no error but the received message is empty as the
# handle method in the server isn't called for each new message
sock.sendall('how are you?')
response = sock.recv(1024)
print "Received: {}".format(response)
except socket.error, (value,message):
print "Error: " + message
finally:
sock.close()
如您所见,每次运行客户端代码时,即使先前的套接字已关闭,也会创建一个新线程……或者至少,threading.current_thread()返回一个新的ID。 如何检查上一个线程是否已停止?
关于@luka的答案; Dietrich是正确的,因为以这种方式使用线程很好。 是的,您只能在给定时间执行一条python指令,但是套接字无论如何通常都是I / O绑定的,所以一切都很好。
知道线程已死亡的最简单方法不是直接从python中获取,因为这与您使用的接口有些相似。 相反,我会看一下可以提供此信息的操作系统。 在Linux上,只需执行pstree
命令。 您的线程数应显示为<thread count>*[{process name}]
,其中线程数是您的线程数。
其他方法包括让您的应用程序打印“状态线程”,“结束线程”或使用调试的python(pydb)。
关于@luka关于事件驱动的python的最后一点,这是一种过早的优化。 如果您不希望应用程序承受巨大的负担,请不必担心。 如果您期望一个巨大的负载,则每个请求的线程派生可能会成为需要解决的瓶颈。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.