2017-08-15 131 views
0

我想在python中创建一个多线程的TCP服务器。 当新客户端被接受时,它会转到新创建的线程。 但是,当较早的客户端发送数据时,它看起来像新创建的线程拦截它们,以便从服务器端看起来只有较新的客户端在说话!多线程TCP服务器python

这里是我的代码:

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客户端发送“你好”的第一个客户,“卓悦”为第二个:

$ 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?! 

为什么第二次发送“你好”没有从线程2弹出?以及如何使它发生,以便我可以从服务器端回复适当的客户端?

非常感谢! (Thread Newbie here:/)

回答

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')而不是每次都重复的日志格式。

+0

这解释了我所处的问题,现在完全解决了。非常感谢! – philippe