繁体   English   中英

python的线程化TCP套接字

[英]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的最后一点,这是一种过早的优化。 如果您不希望应用程序承受巨大的负担,请不必担心。 如果您期望一个巨大的负载,则每个请求的线程派生可能会成为需要解决的瓶颈。

  1. Python是从单线程运行的,因此,如果这是您的目标,那么使用多个线程不会给您带来任何性能提升。 可能会不必要地花费更多的内存。
  2. 我建议使用gevent库来抽象并行执行和处理大量套接字。

http://www.gevent.org/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM