<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 基于 Socket 實(shí)現(xiàn)群聊

          共 4149字,需瀏覽 9分鐘

           ·

          2021-05-24 17:55

          來源:博客園-huny

          https://www.cnblogs.com/huny/p/14051152.html

          【導(dǎo)語】互聯(lián)網(wǎng)時(shí)代,怎么能不懂點(diǎn)網(wǎng)絡(luò)編程?套接字(Sockets)是雙向通信信道的端點(diǎn),本文詳細(xì)介紹了使用Socket實(shí)現(xiàn)類似微信群聊的功能,快進(jìn)來一起學(xué)習(xí)下吧!


          1.前言


          套接字(Sockets)是雙向通信信道的端點(diǎn)。套接字可以在一個(gè)進(jìn)程內(nèi),在同一機(jī)器上的進(jìn)程之間,或者在不同主機(jī)的進(jìn)程之間進(jìn)行通信,主機(jī)可以是任何一臺(tái)有連接互聯(lián)網(wǎng)的機(jī)器。


          套接字可以通過多種不同的通道類型實(shí)現(xiàn):Unix域套接字,TCP,UDP等。套接字庫提供了處理公共傳輸?shù)奶囟悾约耙粋€(gè)用于處理其余部分的通用接口。


          1.1 socket模塊:


          要?jiǎng)?chuàng)建套接字,必須使用套接字模塊中的socket.socket()函數(shù),該函數(shù)具有一般語法

          s = socket.socket (socket_family, socket_type, protocol = 0)


          1.2 常用方法



          2. 示例1


          2.1 服務(wù)器端

          #sever.pyimport socket
          s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)host = socket.gethostname()port = 8088s.bind((host,port))try: while True: receive_data,addr = s.recvfrom(1024) print("來自服務(wù)器" + str(addr) + "的消息:") print(receive_data.decode('utf-8')) msg = input('please input send to msg:') s.sendto(msg.encode('utf-8'),addr)except: s.close()

          2.2 客戶端

          #client.pyimport sockets = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)try:    while True:        host = socket.gethostname()        port = 8088        send_data = input('please input msg:')        s.sendto(send_data.encode('utf-8'),(host,port))        msg,addr = s.recvfrom(1024)        print("來自服務(wù)器" + str(addr) + "的消息:")        print(msg.decode('utf-8'))except:    s.close()

          服務(wù)器示例



          客戶端示例



          簡(jiǎn)易的UDP聊天實(shí)現(xiàn)了,下面我們來優(yōu)化一下示例。


          3.示例優(yōu)化


          服務(wù)端

          #server.pyimport socketimport logging
          def main(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 創(chuàng)建socket對(duì)象
          addr = ('127.0.0.1', 9999) s.bind(addr) # 綁定地址和端口
          logging.info('UDP Server on %s:%s...', addr[0], addr[1])
          user = {} # 存放字典{addr:name} while True: try: data, addr = s.recvfrom(1024) # 等待接收客戶端消息存放在2個(gè)變量data和addr里 if not addr in user: # 如果addr不在user字典里則執(zhí)行以下代碼 for address in user: # 從user遍歷數(shù)據(jù)出來address s.sendto(data + ' 進(jìn)入聊天室...'.encode('utf-8'), address) # 發(fā)送user字典的data和address到客戶端 user[addr] = data.decode('utf-8') # 接收的消息解碼成utf-8并存在字典user里,鍵名定義為addr continue # 如果addr在user字典里,跳過本次循環(huán)
          if 'EXIT'.lower() in data.decode('utf-8'):#如果EXIT在發(fā)送的data里 name = user[addr] #user字典addr鍵對(duì)應(yīng)的值賦值給變量name user.pop(addr) #刪除user里的addr for address in user: #從user取出address s.sendto((name + ' 離開了聊天室...').encode(), address) #發(fā)送name和address到客戶端 else: print('"%s" from %s:%s' %(data.decode('utf-8'), addr[0], addr[1])) for address in user: #從user遍歷出address if address != addr: #address不等于addr時(shí)間執(zhí)行下面的代碼 s.sendto(data, address) #發(fā)送data和address到客戶端
          except ConnectionResetError: logging.warning('Someone left unexcept.')
          if __name__ == '__main__': main()

          客戶端

          #clinet.pyimport socketimport threading
          def recv(sock, addr): ''' 一個(gè)UDP連接在接收消息前必須要讓系統(tǒng)知道所占端口 也就是需要send一次,否則win下會(huì)報(bào)錯(cuò) ''' sock.sendto(name.encode('utf-8'), addr) while True: data = sock.recv(1024) print(data.decode('utf-8'))

          def send(sock, addr): ''' 發(fā)送數(shù)據(jù)的方法 參數(shù): sock:定義一個(gè)實(shí)例化socket對(duì)象 server:傳遞的服務(wù)器IP和端口 ''' while True: string = input('') message = name + ' : ' + string data = message.encode('utf-8') sock.sendto(data, addr) if string.lower() == 'EXIT'.lower(): break
          def main(): ''' 主函數(shù)執(zhí)行方法,通過多線程來實(shí)現(xiàn)多個(gè)客戶端之間的通信 ''' s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server = ('127.0.0.1', 9999) tr = threading.Thread(target=recv, args=(s, server), daemon=True) ts = threading.Thread(target=send, args=(s, server)) tr.start() ts.start() ts.join() s.close()
          if __name__ == '__main__': print("-----歡迎來到聊天室,退出聊天室請(qǐng)輸入'EXIT(不分大小寫)'-----") name = input('請(qǐng)輸入你的名稱:') print('-----------------%s------------------' % name) main()

          支持多人的簡(jiǎn)易聊天室示例,多個(gè)客戶端通過一個(gè)服務(wù)器進(jìn)行之間通信。





          - EOF -

          回復(fù)關(guān)鍵字“簡(jiǎn)明python ”,立即獲取入門必備書籍簡(jiǎn)明python教程》電子版

          回復(fù)關(guān)鍵字爬蟲”,立即獲取爬蟲學(xué)習(xí)資料

          版權(quán)申明:內(nèi)容來源網(wǎng)絡(luò),版權(quán)歸原創(chuàng)者所有。除非無法確認(rèn),都會(huì)標(biāo)明作者及出處,如有侵權(quán),煩請(qǐng)告知,我們會(huì)立即刪除并致歉。我們對(duì)文中觀點(diǎn)保持中立,僅供參考、交流之目的。


          點(diǎn)擊關(guān)注【python入門與進(jìn)階】,閱讀更多精彩內(nèi)容
          ??????

          瀏覽 89
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  欧美熟女在线 | 青草在线视频 | 亚洲精品国产精品乱码桃花 | 航空服务一级特黄A片视频 | 激情啪啪网站 |