python tcp通信如何实现多人聊天,Python实现多用户全双工聊天(一对一),python多用户,多用户全双工聊天简陋...
Python實現多用戶全雙工聊天(一對一),python多用戶,多用戶全雙工聊天簡陋
多用戶全雙工聊天簡陋版
簡單實現了兩個客戶端之間的通信,客戶端發送消息,先由服務器接收,然后服務器轉發到另一客戶端。
該版本功能非常簡陋,僅僅實現了最簡單的聊天,有很多地方需要注意。
工作步驟:服務器端運行一個客戶端運行,連接成功后輸入用戶名,服務器會保存該用戶名在一個字典中,字典的對應關系是 username --> socket輸入用戶名之后,該客戶端需要確定一個聊天用戶,客戶端輸入To:user即可;如果客戶端發送其他文本的話,會收到來自服務器的提示:“Nobody is chatting with you. Maybe the one talked with you is talking with someone else”當兩個客戶端成功連接之后就可以互相發送消息
服務器端代碼如下:#!/usr/bin/python#coding:utf-8#server.pyfrom socket import *from time import ctimeimport threadingimport reHOST = ‘‘PORT = 9999BUFSIZ = 1024ADDR = (HOST,PORT)tcpSerSock = socket(AF_INET,SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)clients = {} # username -> socketchatwith = {} # user1.socket -> user2.socket# clients字典中記錄了連接的客戶端的用戶名和套接字的對應關系# chatwith字典中記錄了通信雙方的套接字的對應# messageTransform()處理客戶端確定用戶名之后發送的文本# 文本只有四種類型:# None# Quit# To:someone# 其他文本def messageTransform(sock,user): while True: data = sock.recv(BUFSIZ) if not data: if chatwith.has_key(sock): chatwith[sock].send(data) del chatwith[chatwith[sock]] del chatwith[sock] del clients[user] sock.close() break if data==‘Quit‘: sock.send(data) if chatwith.has_key(sock): data = ‘%s.‘ % data chatwith[sock].send(data) del chatwith[chatwith[sock]] del chatwith[sock] del clients[user] sock.close() break elif re.match(‘^To:.+‘, data) is not None: data = data[3:] if clients.has_key(data): if data==user: sock.send(‘Please don\‘t try to talk with yourself.‘) else: 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(‘Nobody is chating with you. Maybe the one talked with you is talking with someone else‘) # 每個客戶端連接之后,都會啟動一個新線程# 連接成功后需要輸入用戶名# 輸入的用戶名可能會:# 已存在# (客戶端直接輸入ctrl+c退出)# 合法用戶名def connectThread(sock,test): # client‘s socket user = None while True: # receive the username username = sock.recv(BUFSIZ) if not username: # the client logout without input a name print(‘The client logout without input a name‘) break if clients.has_key(username): # username existed sock.send(‘Reuse‘) else: # correct username sock.send(‘OK‘) clients[username] = sock # username -> socket user = username break if not user: sock.close() return print(‘The username is: %s‘ % user) # get the correct username messageTransform(sock,user) if __name__==‘__main__‘: while True: print(‘...WAITING FOR CONNECTION‘) tcpCliSock, addr = tcpSerSock.accept() print(‘CONNECTED FROM: ‘, addr) chat = threading.Thread(target = connectThread, args = (tcpCliSock,None)) chat.start()
客戶端代碼如下:#!/usr/bin/python#coding:utf-8#client.pyfrom socket import *from time import ctime# from termios import tcflush,TCIFLUSHimport threadingimport sysHOST = ‘127.0.0.1‘PORT = 9999BUFSIZ = 1024ADDR = (HOST,PORT)tcpCliSock = socket(AF_INET,SOCK_STREAM)tcpCliSock.connect(ADDR)‘‘‘因為每個客戶端接收消息和發送消息是相互獨立的,所以這里將兩者分開,開啟兩個線程處理‘‘‘def Send(sock,test): while True: try: data = raw_input() sock.send(data) if data==‘Quit‘: break except KeyboardInterrupt: sock.send(‘Quit‘) break def Recv(sock,test): while True: data = sock.recv(BUFSIZ) if data==‘Quit.‘: print(‘He/She logout‘) continue if data==‘Quit‘: break print(‘ %s‘ % data) if __name__==‘__main__‘: print(‘Successful connection‘) while True: username = raw_input(‘Your name(press only Enter to quit): ‘) tcpCliSock.send(username) if not username: break # username is not None response = tcpCliSock.recv(BUFSIZ) if response==‘Reuse‘: print(‘The name is reuse, please set a new one‘) continue else: print(‘Welcome!‘) break if not username: tcpCliSock.close() recvMessage = threading.Thread(target = Recv, args = (tcpCliSock,None)) sendMessage = threading.Thread(target = Send, args = (tcpCliSock,None)) sendMessage.start() recvMessage.start() sendMessage.join() recvMessage.join()
總結:
功能簡陋,后續會有所改進。這里還有很多地方需要注意。
比如說兩個客戶端A成功連接后,和客戶端B聊天。A發送消息時直接輸入ctrl+c退出程序(sendMessage線程會結束),我將這種情況模擬成A發送Quit登出。服務器接收到A登出信息之后,會回發一個Quit給A,A成功登出(recvMessage線程結束)。此外如果A和B建立了聊天關系,就要接觸這個關系,服務器發送Quit.給B,B會繼續接收信息,但是服務器端的chatwith字典中已經不存在A.socket --> B.socket關系。
但是還有很多沒有解決的問題,比如說客戶端A并沒有輸入信息,直接點擊關閉按鈕退出,就會發生異常(與之聊天的B客戶端會崩潰)。
如果當前存在 A-->B的聊天關系,這時有一個C登錄,并且確定了C-->A的聊天關系,那么A會和C聊天,這時客戶端B就會被掛起。
主要的問題還是在于客戶端非正常登出時的應對,目前解決了一部分問題,但是應該還有不少缺陷。
Python實現多用戶全雙工聊天(一對一)
總結
以上是生活随笔為你收集整理的python tcp通信如何实现多人聊天,Python实现多用户全双工聊天(一对一),python多用户,多用户全双工聊天简陋...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php改成IP连接数据库,thinkph
- 下一篇: 信用卡被起诉会坐牢吗?信用卡被起诉后会立