python實(shí)現(xiàn)多人聊天服務(wù)器以及客戶端
本文實(shí)例為大家分享了python實(shí)現(xiàn)多人聊天服務(wù)器以及客戶端,供大家參考,具體內(nèi)容如下
所用python的知識(shí)點(diǎn):
網(wǎng)絡(luò)編程:socket
多線程:threading
圖形化編程:tkinter
首先要模擬出一個(gè)服務(wù)器,以供客戶端連接,注意這里的要用死循環(huán),要讓服務(wù)區(qū)一直處于開放的狀態(tài)
其次要運(yùn)用多線程,因?yàn)槎嗑€程共享變量而且可以同時(shí)并發(fā)的執(zhí)行操作,否則服務(wù)器就只可以連接一個(gè)客戶端
下面先附上代碼后在解釋其怎么操作:
第一個(gè)py文件--服務(wù)器
import tkinter import socket, threading win = tkinter.Tk() # 創(chuàng)建主窗口 win.title('模擬服務(wù)器') win.geometry("400x400+200+20") users = {}#用戶字典,也可以連接數(shù)據(jù)庫(kù) def run(ck, ca): userName = ck.recv(1024)#接受客戶端發(fā)送的信息以1k作為單位這里接受到的信息為byte類型 users[userName.decode("utf-8")] = ck#解碼并儲(chǔ)存用戶的信息 #print(users) printStr = "" + userName.decode("utf-8") + "連接\n"#在連接顯示框中顯示是否連接成功 text.insert(tkinter.INSERT, printStr) while True: rData = ck.recv(1024)#接受客戶端發(fā)送的信息以1k作為單位這里接受到的信息為byte類型 dataStr = rData.decode("utf-8") infolist = dataStr.split(":")#分割字符串從而得到所要發(fā)送的用戶名和客戶端所發(fā)送的信息 users[infolist[0]].send((userName.decode("utf-8") + "說(shuō)" + infolist[1]).encode("utf")) #要發(fā)送信息的客戶端向目標(biāo)客戶端發(fā)送信息 def start(): ipStr = eip.get()#從輸入端中獲取ip portStr = eport.get()#從輸入端中獲取端口,注意端口取得時(shí)候不能被占用(可以取8080,9876,等) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#socked所準(zhǔn)守ipv4或ipv6,和相關(guān)協(xié)議的 server.bind((ipStr, int(portStr)))#綁定ip和端口號(hào)?。?!1:注意輸入的端口號(hào)是str型而這里的要傳入int型 #2:bind()的參數(shù)是一個(gè)元組的形式 server.listen(10)#設(shè)置監(jiān)聽(tīng),和設(shè)置連接的最大的數(shù)量 printStr = "服務(wù)器啟動(dòng)成功\n"#,是否連接成功 text.insert(tkinter.INSERT, printStr)#顯示在信息窗口中 while True:#這里用死循環(huán)是因?yàn)槟M的服務(wù)器要一直運(yùn)行 ck, ca = server.accept()#接受所連接的客戶端的信息 # 其中ca是ip和端口號(hào)組成的元組,ck有關(guān)客戶端的信息 t = threading.Thread(target=run, args=(ck, ca))#每連接一個(gè)客戶端就開啟一個(gè)線程 #其中Thread函數(shù)中的傳入函數(shù)的參數(shù)也是以元組的形式 t.start()#開啟線程 def startSever(): s = threading.Thread(target=start)#啟用一個(gè)線程開啟服務(wù)器 s.start()#開啟線程 #下面是關(guān)于界面的操作 labelIp = tkinter.Label(win, text='ip').grid(row=0, column=0) labelPort = tkinter.Label(win, text='port').grid(row=1, column=0) eip = tkinter.Variable() eport = tkinter.Variable() entryIp = tkinter.Entry(win, textvariable=eip).grid(row=0, column=1) entryPort = tkinter.Entry(win, textvariable=eport).grid(row=1, column=1) button = tkinter.Button(win, text="啟動(dòng)", command=startSever).grid(row=2, column=0) text = tkinter.Text(win, height=5, width=30) labeltext = tkinter.Label(win, text='連接消息').grid(row=3, column=0) text.grid(row=3, column=1) win.mainloop()
第二個(gè)py文件---客戶端
import tkinter import socket import threading win = tkinter.Tk() win.title("客戶端2") win.geometry("400x400+200+20") ck = None#用于儲(chǔ)存客戶端的信息 def getInfo(): while True: data = ck.recv(1024)#用于接受服務(wù)其發(fā)送的信息 text.insert(tkinter.INSERT, data.decode("utf-8"))#顯示在信息框上 def connectServer(): global ck ipStr = eip.get() portStr = eport.get() userStr = euser.get() client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#socked所準(zhǔn)守ipv4或ipv6,和相關(guān)協(xié)議的 client.connect((ipStr, int(portStr)))#連接ip和端口號(hào)?。?!1:注意輸入的端口號(hào)是str型而這里的要傳入int型 #2:bind()的參數(shù)是一個(gè)元組的形式 client.send(userStr.encode("utf-8")) ck = client t = threading.Thread(target=getInfo) t.start() def sendMail(): friend = efriend.get() sendStr = esend.get() sendStr = friend + ":" + sendStr ck.send(sendStr.encode("utf-8")) #下面是界面 labelUse = tkinter.Label(win, text="userName").grid(row=0, column=0) euser = tkinter.Variable() entryUser = tkinter.Entry(win, textvariable=euser).grid(row=0, column=1) labelIp = tkinter.Label(win, text="ip").grid(row=1, column=0) eip = tkinter.Variable() entryIp = tkinter.Entry(win, textvariable=eip).grid(row=1, column=1) labelPort = tkinter.Label(win, text="port").grid(row=2, column=0) eport = tkinter.Variable() entryPort = tkinter.Entry(win, textvariable=eport).grid(row=2, column=1) button = tkinter.Button(win, text="啟動(dòng)", command=connectServer).grid(row=3, column=0) text = tkinter.Text(win, height=5, width=30) labeltext= tkinter.Label(win, text="顯示消息").grid(row=4, column=0) text.grid(row=4, column=1) esend = tkinter.Variable() labelesend = tkinter.Label(win, text="發(fā)送的消息").grid(row=5, column=0) entrySend = tkinter.Entry(win, textvariable=esend).grid(row=5, column=1) efriend = tkinter.Variable() labelefriend= tkinter.Label(win, text="發(fā)給誰(shuí)").grid(row=6, column=0) entryFriend = tkinter.Entry(win, textvariable=efriend).grid(row=6, column=1) button2 = tkinter.Button(win, text="發(fā)送", command=sendMail).grid(row=7, column=0) win.mainloop()
這里的客戶端可以是多個(gè),也就是將第二個(gè)py文件復(fù)制幾分并分別儲(chǔ)存在不同的文件中
這里注意:在pycharm中最好在一個(gè)項(xiàng)目中打開
1:將第一個(gè)文件命名為sever.py然后運(yùn)行sever.py文件會(huì)出現(xiàn)
其中第一行表示你的主機(jī)的ipv4地址,如果你用的window,不知道的可以打開cmd后輸入ipconfig可以看到你的ipv4地址
第二行表示的是端口,這里最好用大一點(diǎn)8080或9876等,要不就會(huì)出現(xiàn)端口占用情況,這里我用9876
最后輸入前兩行后點(diǎn)擊啟動(dòng)
2、將第二個(gè)文件多復(fù)制遍,分別命名為01.py,02.py......,運(yùn)行01.py文件
這里第一行輸入的是你的用戶名,注意可以是任意的字符
第二行輸入的是你要連接的服務(wù)器的ip這里寫你的ip(和上面的ip一樣)
第三行輸入的是端口注意第一個(gè)圖上寫的端口保持一致上
然后點(diǎn)擊啟動(dòng)
然后在運(yùn)行02.py,重復(fù)01.py中的操作但是注意用戶名不能相同,二ip和端口號(hào)是相同的
如果你想更多的連接更多的客戶端可以運(yùn)行0.3.py重復(fù)02.py操作
3、到這里假設(shè)你創(chuàng)建了01.py和02.py并運(yùn)行其中0.1.py中的userName為123,02.py的userName為456并且連個(gè)ip和端口號(hào)和sever.py中的ip和端口號(hào)相同,然后就可以操作兩個(gè)人的聊天了
打開運(yùn)行01.py后的界面輸入
然后點(diǎn)擊發(fā)送
然后打開02.py運(yùn)行后的界面會(huì)出現(xiàn)下面的
這樣就實(shí)現(xiàn)了用python模擬多人聊天服務(wù)器以及客戶端(帶圖形化界面)的目標(biāo)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- python的tkinter布局之簡(jiǎn)單的聊天窗口實(shí)現(xiàn)方法
- 教你用Python創(chuàng)建微信聊天機(jī)器人
- python操作微信自動(dòng)發(fā)消息的實(shí)現(xiàn)(微信聊天機(jī)器人)
- 基于Python如何使用AIML搭建聊天機(jī)器人
- 快速實(shí)現(xiàn)基于Python的微信聊天機(jī)器人示例代碼
- Python實(shí)現(xiàn)聊天機(jī)器人的示例代碼
- Python QQBot庫(kù)的QQ聊天機(jī)器人
- python實(shí)現(xiàn)聊天小程序
- Python基于Socket實(shí)現(xiàn)的簡(jiǎn)單聊天程序示例
- 使用Python AIML搭建聊天機(jī)器人的方法示例
相關(guān)文章
淺談TensorFlow中讀取圖像數(shù)據(jù)的三種方式
這篇文章主要介紹了淺談TensorFlow中讀取圖像數(shù)據(jù)的三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Python內(nèi)置函數(shù)——__import__ 的使用方法
本篇文章主要介紹了Python內(nèi)置函數(shù)——__import__ 的使用方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11利用QT寫一個(gè)極簡(jiǎn)單的圖形化Python鬧鐘程序
這篇文章主要介紹了利用QT寫一個(gè)極簡(jiǎn)單的圖形化Python鬧鐘程序,核心代碼只有25行,顯示屏幕提示而沒(méi)有鬧鈴聲音,需要的朋友可以參考下2015-04-04python正則表達(dá)式去掉數(shù)字中的逗號(hào)(python正則匹配逗號(hào))
在處理自然語(yǔ)言時(shí)123,000,000如果以標(biāo)點(diǎn)符號(hào)分割,就會(huì)出現(xiàn)問(wèn)題,好好的一個(gè)數(shù)字就被逗號(hào)肢解了,因此可以先下手把數(shù)字處理干凈(逗號(hào)去掉)2013-12-12解決Keras自帶數(shù)據(jù)集與預(yù)訓(xùn)練model下載太慢問(wèn)題
這篇文章主要介紹了解決Keras自帶數(shù)據(jù)集與預(yù)訓(xùn)練model下載太慢問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-06-06Python實(shí)現(xiàn)復(fù)制圖片到指定文件夾并按順序重新命名
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)將360個(gè)文件夾里的照片,全部復(fù)制到指定的文件夾中,并且按照順序重新命名,感興趣的小伙伴可以了解一下2023-03-03