<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用 Python 開發(fā)一個 【聊天室】

          共 2777字,需瀏覽 6分鐘

           ·

          2020-06-17 23:22

          接下來我們就使用 Python 來操作 socket ,實(shí)現(xiàn)一個聊天室的一些主要功能。首先我們來回想下,一般的聊天室都是怎樣的,有多個用戶可以同時在線,他們可以實(shí)時獲取到消息,實(shí)時發(fā)送消息。

          服務(wù)端的實(shí)現(xiàn)
          那么服務(wù)端要實(shí)現(xiàn)的就有這么幾點(diǎn):

          • 監(jiān)聽客戶端的連接
          • 同時操作多個用戶
          • 廣播消息通知

          代碼擼起來:
          因?yàn)槲覀円龅?“同時” 去操作用戶,就需要用到多線程:
          import socket
          from threading import Thread

          接著創(chuàng)建一下 socket ,綁定地址和端口號:
          host = '127.0.0.1'
          port = 8080

          s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          s.bind((host, port))

          我們可以定義字典來存放用戶的數(shù)據(jù),比如連接用戶的昵稱以及地址:
          client = {}
          addresses = {}

          再來定義下服務(wù)器可接收的 client 連接數(shù):
          accept_num = 10

          接下來可以在 main 方法在監(jiān)聽用戶的連接:
          if __name__ == '__main__':??????s.listen(accept_num)
          print('服務(wù)器已經(jīng)開啟,正在監(jiān)聽用戶的請求..')

          接著可以寫一個 whie 循環(huán)來接收用戶的連接:
          while True:         conn, address = s.accept()
          print(address, '已經(jīng)建立連接')
          conn.send('歡迎你來到帥帥的聊天室,
          請輸入你的昵稱進(jìn)行聊天'.encode('utf8'))

          接收到用戶的連接之后,我們就可以獲取到用戶的連接和地址信息,可以把地址保存到我們剛剛定義的字典里面來:
          addresses[conn] = address

          要支持多個用戶的信息收發(fā),我們可以開啟線程:
          Thread(target=handle_client_in, args=(conn, address)).start()

          至此,我們的 main 方法是這樣的:

          87da0976542a00cef47a149a358bb455.webp



          接著我們來實(shí)現(xiàn)一下用戶的消息處理方法,我們可以接收用戶發(fā)來的昵稱消息,這時候就可以在聊天室里面進(jìn)行廣播,告訴大家 “xxx 加進(jìn)來了”,另外我們可以把用戶的昵稱加到字典中來:
          def handle_client_in(conn, addr):
          nikename = conn.recv(1024).decode('utf8')
          welcome = f'歡迎 {nikename} 加入聊天室'
          client[conn] = nikename
          brodcast(bytes(welcome, 'utf8'))

          接下來可以定義一個 While 循環(huán),來監(jiān)聽用戶發(fā)送的消息,當(dāng)服務(wù)端獲取到用戶發(fā)來的消息之后,我們可以在聊天室進(jìn)行廣播,告訴大家 “xxx 發(fā)來了 xxx 消息”,而當(dāng)用戶由于異常而退出聊天室的時候,我們可以將連接關(guān)掉,并且把字典存著的用戶數(shù)據(jù)給刪掉:
          while True:
          | try:
          | | msg = conn.recv(1024)
          | | brodcast(msg, nikename+':')
          | except:
          | | conn.close()
          | | del client[conn]
          | | brodcast(bytes(f'{nikename} 離開聊天室', 'utf8')
          )

          那么如何對聊天室的用戶進(jìn)行廣播呢,因?yàn)槲覀儎倓傇谧值渲卸即鎯α诉B接進(jìn)來的用戶連接,那么就可以通過循環(huán)的方式向每個用戶發(fā)送消息:
          def brodcast(msg, nikename=''):
          for conn in client:
          conn.send(bytes(nikename, 'utf8') + msg)

          這樣,一個聊天室的服務(wù)端主要功能就完成了:


          14170d7c84dcab129a23e3fedfd6291d.webp



          這時候就可以坐等用戶的連接,接下來小帥b再跟你說下如何實(shí)現(xiàn)聊天室的客戶端,如何讓人們進(jìn)來吹水。
          客戶端的實(shí)現(xiàn)
          一般來說,客戶端的操作越傻瓜式越好,我們主要實(shí)現(xiàn)這樣的功能:

          • 用戶可以運(yùn)行一個聊天室軟件
          • 可以在里面看到所有聊天室用戶的消息
          • 自己可以編輯消息進(jìn)行發(fā)送

          我們可以使用 tkinter 這個庫來寫一些 Python 的 GUI ,也就是客戶端的聊天界面,首先導(dǎo)入 tk 庫,然后定義一下標(biāo)題:

          034fc25859b91f15fece29b272d7cfb4.webp

          運(yùn)行一下就是這樣的:

          17991cf69cfbbaa9b2ac4efb1b929a03.webp

          創(chuàng)建聊天界面布局


          創(chuàng)建面板


          接下來我們來創(chuàng)建聊天界面的布局,先定義三個面板,分別是用來看消息的面板,輸入消息的面板,以及發(fā)送消息的面板:

          13538c52389b60e1a2866eed967901ea.webp

          創(chuàng)建文本和按鈕


          消息面板和發(fā)送消息面板都是 Text , 而發(fā)送的操作需要用到 Button:

          f95f2ddf17ee3acf82be312c8fe89035.webp

          容器位置排放


          消息窗口位于第 1 行,消息輸入窗口位于第 2 行,發(fā)送按鈕位于第三行:

          8137495e0bb9f10a6bf6a432e307db96.webp

          固定容器大小


          可以使用 grid_propagate 來固定各個面板的大小:

          d4b209f13b6c9a8c355b6f30148ae730.webp

          文本按鈕添加到容器中


          最后將剛剛定義的 text 和 Button 弄進(jìn)來:

          f4e52f8872a3c1ef15e5be24a53c0d22.webp

          運(yùn)行一下:

          2ea4b417bb54abcf9ac9135ba1d29103.webp

          這樣我們的聊天界面就做好了,接下來需要綁定一下事件,也就是說,當(dāng)我們點(diǎn)擊發(fā)送按鈕的時候,應(yīng)該要觸發(fā)一個事件,我們可以通過這個時間將輸入框中的內(nèi)容發(fā)送給 socket 服務(wù)端。

          發(fā)送事件綁定


          我們可以在剛剛定義的 Button 中使用 command 參數(shù)來綁定方法,從而實(shí)現(xiàn)點(diǎn)擊發(fā)送按鈕時候的觸發(fā):

          e8c4a2c86e0619fc7f3d2a10790e959b.webp

          這里我們定義的名稱是 send , 所以我們可以定義一個 send 方法來進(jìn)一步操作:

          4c9140051edd9bf5e7a930f46e34cfba.webp

          當(dāng)我們點(diǎn)擊按鈕的時候就會觸發(fā)這個方法:
          ae76f48e5cf832e294e945890fde8518.webp
          ok,那么接下來就是在 send 方法中獲取輸入框中的內(nèi)容,發(fā)送給 socket ,然后再清空輸入框中的內(nèi)容:

          5c31918268db4525d1eeea26dc5211c4.webp

          我們先把獲取和清空實(shí)現(xiàn)下看看:

          349914e69b2cffb631e827dc61626157.webp

          ok,沒問題之后,我們就開始接入 socket 。

          Socket 的接入


          像我們之前說的那樣,定義一下連接的 socket 地址信息,然后創(chuàng)建連接:

          f98ffffd744aac4d5eed7201546da0b4.webp

          接著可以創(chuàng)建線程來接收服務(wù)器發(fā)過來的消息:

          35ef0ea5ce18987255ba7e91aff9ea47.webp

          將服務(wù)器獲取到的消息展示到消息面板中:

          c946343ff669bcc93ecc0398f6c2bf67.webp

          Socket 消息發(fā)送


          我們再回到剛剛定義的 send 方法,把要發(fā)送的消息通過 socket 發(fā)送過去:

          c726b0e3ae62e49b13e857f682cd698b.webp

          運(yùn)行聊天室


          接下來我們就來運(yùn)行一下我們寫的聊天室,首先運(yùn)行我們寫的 socket 服務(wù)端:

          93f4e143f1a61310ded9a10e8791324c.webp

          接著開啟客戶端:

          69416504f33b7fbe4ffa5f62fec4a7e1.webp

          連接正常,這時候已經(jīng)可以交互了,我們再打開一個客戶端:

          d91b15af979a896928647f1574a887d3.webp

          可以接收到消息了,我們讓他們聊起來看看:
          7715955f73148b00948483884d454a59.webp
          ok,這樣聊天室的主要功能就實(shí)現(xiàn)啦,當(dāng)然還有一些小地方的界面可以優(yōu)化,這篇主要還是跟你說說 socket 的應(yīng)用,本文首發(fā)于 fxxkpython.com,更多精彩可以點(diǎn)擊閱讀原文查看。
          那么,我們下回見,peace!
          瀏覽 83
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天干在线观看 | 色哟哟哟精品 | 国产在线自在拍在线观看 | 小说乱伦视频网站 | 色逼123 |