本文實例講述了Python網絡編程基于多線程實現多用戶全雙工聊天功能。分享給大家供大家參考,具體如下:
在前面一篇《Python網絡編程使用select實現socket全雙工異步通信功能》中,我們實現了1對1的異步通信,在文章結尾,給出了多對多通信的思路。
既然說了,咱就動手試一試,本次用的是多線程來實現,正好練練手~
首先講一下思路:
我們將服務器做為中轉站來處理信息,一方面與客戶端互動,另一方面進行消息轉發。
大體思路確定下來后,需要確定一些通信規則:
1. 客戶端與服務器建立連接后,需要輸入用戶名登入,若用戶名已存在,將reuse反饋給用戶,用戶輸出錯誤信息,退出
2. 用戶輸入正確的用戶名后,即可進行通信了。如果未選擇通信對象,則服務器會反饋信息,提示用戶選擇通信對象
3. 選擇通信對象的方法為,輸入to:username,如果所選擇的對象不存在,反饋錯誤信息,重新輸入
4.當正確選擇通信對象后,雙方建立連接,通過服務器中轉信息進行通信
5.在通信中,若發送‘quit',則結束發送消息的線程,并指示服務器該用戶準備登出,服務器刪除該用戶后,反饋消息給用戶,用戶結束接收消息的線程并退出
6.如果A正在與C通信,此時B向A發送信息,則A的通信窗口變為與B的通信窗口,即接收到B消息后,A發出的消息不再是給C,而是默認給B
實現代碼:
#!/usr/bin/python'test TCP server'from socket import *from time import ctimeimport threading #多線程模塊import re #正則表達式模塊HOST = ''PORT = 21567BUFSIZ = 1024ADDR = (HOST, PORT)def Deal(sock, user): while True: data = sock.recv(BUFSIZ) #接收用戶的數據 if data == 'quit': #用戶退出 del clients[user] sock.send(data) sock.close() print '%s logout' %user break elif re.match('to:.+', data) is not None: #選擇通信對象 data = data[3:] if clients.has_key(data): chatwith[sock] = clients[data] chatwith[clients[data]] = sock else: sock.send('the user %s is not exist' %data) else: if chatwith.has_key(sock): #進行通信 chatwith[sock].send("[%s] %s: %s" %(ctime(), user, data)) else: sock.send('Please input the user who you want to chat with')tcpSerSock = socket(AF_INET, SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)clients = {} #提供 用戶名->socket 映射chatwith = {} #提供通信雙方映射while True: print 'waiting for connection...' tcpCliSock, addr = tcpSerSock.accept() print '...connected from:',addr username = tcpCliSock.recv(BUFSIZ) #接收用戶名 print 'The username is:',username if clients.has_key(username): #查找用戶名 tcpCliSock.send("Reuse") #用戶名已存在 tcpCliSock.close() else: tcpCliSock.send("Welcome!") #登入成功 clients[username] = tcpCliSock chat = threading.Thread(target = Deal, args = (tcpCliSock,username)) #創建新線程進行處理 chat.start() #啟動線程tcpSerSock.close()
新聞熱點
疑難解答