您好,登錄后才能下訂單哦!
使用Python怎么實現一個網絡聊天室功能?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
i. 掌握利用Socket進行編程的技術
ii. 掌握多線程技術,保證雙方可以同時發送
iii. 建立聊天工具
iv. 可以和單人聊天
v. 可以和多個人同時進行聊天
vi. 使用圖形界面,顯示雙方的語錄
vii. 程序可以在一定程度上進行錯誤識別
實驗通過聊天室可以完成單人或多人之間的聊天通信,功能的實現主要是通過Socket通信來實現。本次實驗采用客戶端/服務器(C/S)架構模式,通過Python語言來編寫服務器端與客戶端的程序。運用多線程可完成多點對多點的聊天。
服務器端程序主要用于接收用戶信息,消息接收與轉發。
客戶端程序實現用戶注冊登錄,聊天信息顯示與信息輸入。
統計當前在線人數,并且將新用戶加到用戶列表中。
Serve.py
這是服務器對于聊天服務的實現。
通過繼承threading.Thread類而實現多線程,重寫run函數。
接受來自客戶端的用戶名,如果用戶名為空,使用用戶的IP與端口作為用戶名。如果用戶名出現重復,則在出現的用戶名依此加上后綴“2”、“3”、“4”……
在獲取用戶名后便會不斷地接受用戶端發來的消息(即聊天內容),結束后關閉連接。
如果用戶斷開連接,將該用戶從用戶列表中刪除,然后更新用戶列表。
將地址與數據(需發送給客戶端)存入messages隊列。
服務端在接受到數據后,會對其進行一些處理然后發送給客戶端,如下圖,對于聊天內容,服務端直接發送給客戶端,而對于用戶列表,便由json.dumps處理后發送。
Client.py
建立連接,發送用戶名及判斷是否為私聊消息,私聊用~識別
接受來自服務器發送的消息
對接收到的消息進行判斷,如果是在線用戶列表(用json.dumps處理過),便清空在線用戶列表框,并將此列表輸出在在線用戶列表框中。
如果是聊天內容,便將其輸出在聊天內容顯示框中。
設置登錄窗口
設置消息界面
設置在線用戶列表。
完整代碼:
Serve.py
import socket import threading import queue import json # json.dumps(some)打包 json.loads(some)解包 import os import os.path import sys IP = '127.0.0.1' PORT = 9999 # 端口 messages = queue.Queue() users = [] # 0:userName 1:connection lock = threading.Lock() def onlines(): # 統計當前在線人員 online = [] for i in range(len(users)): online.append(users[i][0]) return online class ChatServer(threading.Thread): global users, que, lock def __init__(self): # 構造函數 threading.Thread.__init__(self) self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) os.chdir(sys.path[0]) # 接受來自客戶端的用戶名,如果用戶名為空,使用用戶的IP與端口作為用戶名。如果用戶名出現重復,則在出現的用戶名依此加上后綴“2”、“3”、“4”…… def receive(self, conn, addr): # 接收消息 user = conn.recv(1024) # 用戶名稱 user = user.decode() if user == '用戶名不存在': user = addr[0] + ':' + str(addr[1]) tag = 1 temp = user for i in range(len(users)): # 檢驗重名,則在重名用戶后加數字 if users[i][0] == user: tag = tag + 1 user = temp + str(tag) users.append((user, conn)) USERS = onlines() self.Load(USERS,addr) # 在獲取用戶名后便會不斷地接受用戶端發來的消息(即聊天內容),結束后關閉連接。 try: while True: message = conn.recv(1024) # 發送消息 message = message.decode() message = user + ':' + message self.Load(message,addr) conn.close() # 如果用戶斷開連接,將該用戶從用戶列表中刪除,然后更新用戶列表。 except: j = 0 # 用戶斷開連接 for man in users: if man[0] == user: users.pop(j) # 服務器段刪除退出的用戶 break j = j+1 USERS = onlines() self.Load(USERS,addr) conn.close() # 將地址與數據(需發送給客戶端)存入messages隊列。 def Load(self, data, addr): lock.acquire() try: messages.put((addr, data)) finally: lock.release() # 服務端在接受到數據后,會對其進行一些處理然后發送給客戶端,如下圖,對于聊天內容,服務端直接發送給客戶端,而對于用戶列表,便由json.dumps處理后發送。 def sendData(self): # 發送數據 while True: if not messages.empty(): message = messages.get() if isinstance(message[1], str): for i in range(len(users)): data = ' ' + message[1] users[i][1].send(data.encode()) print(data) print('\n') if isinstance(message[1], list): data = json.dumps(message[1]) for i in range(len(users)): try: users[i][1].send(data.encode()) except: pass def run(self): self.s.bind((IP,PORT)) self.s.listen(5) q = threading.Thread(target=self.sendData) q.start() while True: conn, addr = self.s.accept() t = threading.Thread(target=self.receive, args=(conn, addr)) t.start() self.s.close() if __name__ == '__main__': cserver = ChatServer() cserver.start()
Client.py
import socket import tkinter import tkinter.messagebox import threading import json import tkinter.filedialog from tkinter.scrolledtext import ScrolledText IP = '' PORT = '' user = '' listbox1 = '' # 用于顯示在線用戶的列表框 show = 1 # 用于判斷是開還是關閉列表框 users = [] # 在線用戶列表 chat = '------Group chat-------' # 聊天對象 #登陸窗口 root0 = tkinter.Tk() root0.geometry("300x150") root0.title('用戶登陸窗口') root0.resizable(0,0) one = tkinter.Label(root0,width=300,height=150,bg="LightBlue") one.pack() IP0 = tkinter.StringVar() IP0.set('') USER = tkinter.StringVar() USER.set('') labelIP = tkinter.Label(root0,text='IP地址',bg="LightBlue") labelIP.place(x=20,y=20,width=100,height=40) entryIP = tkinter.Entry(root0, width=60, textvariable=IP0) entryIP.place(x=120,y=25,width=100,height=30) labelUSER = tkinter.Label(root0,text='用戶名',bg="LightBlue") labelUSER.place(x=20,y=70,width=100,height=40) entryUSER = tkinter.Entry(root0, width=60, textvariable=USER) entryUSER.place(x=120,y=75,width=100,height=30) def Login(*args): global IP, PORT, user IP, PORT = entryIP.get().split(':') user = entryUSER.get() if not user: tkinter.messagebox.showwarning('warning', message='用戶名為空!') else: root0.destroy() loginButton = tkinter.Button(root0, text ="登錄", command = Login,bg="Yellow") loginButton.place(x=135,y=110,width=40,height=25) root0.bind('<Return>', Login) root0.mainloop() # 建立連接 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((IP, int(PORT))) if user: s.send(user.encode()) # 發送用戶名 else: s.send('用戶名不存在'.encode()) user = IP + ':' + PORT # 聊天窗口 root1 = tkinter.Tk() root1.geometry("640x480") root1.title('群聊') root1.resizable(0,0) # 消息界面 listbox = ScrolledText(root1) listbox.place(x=5, y=0, width=640, height=320) listbox.tag_config('tag1', foreground='red',backgroun="yellow") listbox.insert(tkinter.END, '歡迎進入群聊,大家開始聊天吧!', 'tag1') INPUT = tkinter.StringVar() INPUT.set('') entryIuput = tkinter.Entry(root1, width=120, textvariable=INPUT) entryIuput.place(x=5,y=320,width=580,height=170) # 在線用戶列表 listbox1 = tkinter.Listbox(root1) listbox1.place(x=510, y=0, width=130, height=320) def send(*args): message = entryIuput.get() + '~' + user + '~' + chat s.send(message.encode()) INPUT.set('') sendButton = tkinter.Button(root1, text ="\n發\n\n\n送",anchor = 'n',command = send,font=('Helvetica', 18),bg = 'white') sendButton.place(x=585,y=320,width=55,height=300) root1.bind('<Return>', send) def receive(): global uses while True: data = s.recv(1024) data = data.decode() print(data) try: uses = json.loads(data) listbox1.delete(0, tkinter.END) listbox1.insert(tkinter.END, "當前在線用戶") listbox1.insert(tkinter.END, "------Group chat-------") for x in range(len(uses)): listbox1.insert(tkinter.END, uses[x]) users.append('------Group chat-------') except: data = data.split('~') message = data[0] userName = data[1] chatwith = data[2] message = '\n' + message if chatwith == '------Group chat-------': # 群聊 if userName == user: listbox.insert(tkinter.END, message) else: listbox.insert(tkinter.END, message) elif userName == user or chatwith == user: # 私聊 if userName == user: listbox.tag_config('tag2', foreground='red') listbox.insert(tkinter.END, message, 'tag2') else: listbox.tag_config('tag3', foreground='green') listbox.insert(tkinter.END, message,'tag3') listbox.see(tkinter.END) r = threading.Thread(target=receive) r.start() # 開始線程接收信息 root1.mainloop() s.close()
關于使用Python怎么實現一個網絡聊天室功能問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。