【问题标题】:multithreaded tcp server python多线程 tcp 服务器 python
【发布时间】:2018-01-23 09:50:23
【问题描述】:

我正在尝试在 python 中创建一个多线程 TCP 服务器。 当一个新客户端被接受时,它会转到一个新创建的线程。 然而,当较早的客户端发送数据时,看起来新创建的线程会拦截它们,因此从服务器端看起来只有较新的客户端在说话!

这是我的代码:

Nbre = 1

class ClientThread(threading.Thread):

   def __init__(self, channel, connection):
      global Nbre
      Nbre = Nbre + 1
      print("This is thread "+str(Nbre)+" speaking")
      self.channel = channel
      self.connection = connection
      threading.Thread.__init__(self)

   def run(self):
      print(connection[0]+':'+str(connection[1])+'<'+str(Nbre)'> Connected!')
      try:
         while True:
             data = self.channel.recv(1024)
             if data:
               print(connection[0]+':'+str(connection[1])+'<'+str(Nbre)+'> '+str(data.strip('\n')))
             else:
               break
      finally:
         print(connection[0]+':'+str(connection[1])+'<'+str(Nbre)+'> Exited!')
         self.channel.close()

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('', 4747))
server.listen(0)
while True:
   channel, connection = server.accept()
   ClientThread(channel, connection).start()

这是我在启动时得到的结果,telnet 客户端为第一个客户端发送“Hello”,为第二个客户端发送“Bonjour”:

 $ python simple_thread.py 
This is thread 2 speaking  # new connection
127.0.0.1:33925> Connected!
127.0.0.1:33925<2> hello
This is thread 3 speaking  # new connection
127.0.0.1:33926> Connected!
127.0.0.1:33926<3> Bonjour # last connected says "Bonjour" (ok here)
127.0.0.1:33926<3> hello   # first connected re-send "hello" but in thread 3?!

为什么第二次发送的“hello”没有从线程 2 弹出?以及如何做到这一点,以便我可以从服务器端回复到适当的客户端?

非常感谢! (这里是线程新手:/)

【问题讨论】:

    标签: python multithreading tcp


    【解决方案1】:

    好消息是,它可能有效,但您的日志记录已损坏。这里使用Nbre,是线程数,不是当前线程数:

               print(connection[0]+':'+str(connection[1])+'<'+str(Nbre)+'> '+str(data.strip('\n')))
    

    因此,要使这项工作正常进行,请将当前线程的编号存储在线程对象上,然后改用它。像这样的:

       def __init__(self, channel, connection):
         global Nbre
         Nbre = Nbre + 1
         self.number = Nbre
    

    connection 对象也存在类似问题。日志记录使用connection 而不是self.connection。通常你会得到一个错误,但是因为底部的while 循环创建了一个全局的connection 变量,所以它会被拾取。所以请在日志中使用self.connection

    为了您自己的理智,我还建议将日志记录提取到一个函数中,并使用string.format

    def log(self, message):
       print('{}:{}<{}> {}'.format(self.connection[0], str(self.connection[1]), self.number, message)
    

    所以你可以只写self.log('Thread started'),而不是每次都重复日志格式。

    【讨论】:

    • 这正好解释了我遇到的麻烦,现在完全解决了。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    相关资源
    最近更新 更多