多线程TCP服务器python
问题描述:
我想在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:/)
答
好消息是,它可能有效,但是你的日志记录被破坏了。在这里,您使用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')
而不是每次都重复的日志格式。
这解释了我所处的问题,现在完全解决了。非常感谢! – philippe