一、說明
本文主要使用socket.socket發送UDP廣播來實現聊天室功能。
重點難點:理解UDP通訊流程、多線程、UDP廣播收發等。
測試環境:Win10\Python3.5。
程序基本流程:創建接收端socket ---> 創建發送到socket ---> 啟動接收端socket ---> 啟動發送端socket ---> 等待用戶輸入 ---> 接收用戶輸入並發送到廣播 ---> 接收信息並顯示。
二、程序運行圖
如圖所示,啟動了兩個客戶端(端口號分別為60649、60652)以及啟動一個網絡測試工具(測試工具只發),客戶端1發送hello,客戶端2可以接收到此廣播並顯示。
三、源碼
1 # -*- coding:utf-8 -*- 2 3 from socket import * 4 from time import ctime, sleep 5 import threading 6 7 8 class ChatRoomPlus: 9 def __init__(self): 10 # 全局參數配置 11 self.encoding = "utf-8" # 使用的編碼方式 12 self.broadcastPort = 7788 # 廣播端口 13 14 # 創建廣播接收器 15 self.recvSocket = socket(AF_INET, SOCK_DGRAM) 16 self.recvSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) 17 self.recvSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) 18 self.recvSocket.bind(('', self.broadcastPort)) 19 20 # 創建廣播發送器 21 self.sendSocket = socket(AF_INET, SOCK_DGRAM) 22 self.sendSocket.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) 23 24 # 其他 25 self.threads = [] 26 27 def send(self): 28 """發送廣播""" 29 30 print("UDP發送器啟動成功...") 31 self.sendSocket.sendto("***加入了聊天室".encode(self.encoding), ('255.255.255.255', self.broadcastPort)) 32 while True: 33 sendData = input("請輸入需要發送的消息:") 34 35 self.sendSocket.sendto(sendData.encode(self.encoding), ('255.255.255.255', self.broadcastPort)) 36 # print("【%s】%s:%s" % (ctime(), "我", sendData)) 37 38 sleep(1) 39 40 def recv(self): 41 """接收廣播""" 42 43 print("UDP接收器啟動成功...") 44 while True: 45 # 接收數據格式:(data, (ip, port)) 46 recvData = self.recvSocket.recvfrom(1024) 47 48 print("【%s】[%s : %s] : %s" % (ctime(), recvData[1][0], recvData[1][1], recvData[0].decode(self.encoding))) 49 50 sleep(1) 51 52 def start(self): 53 """啟動線程""" 54 55 t1 = threading.Thread(target=self.recv) 56 t2 = threading.Thread(target=self.send) 57 self.threads.append(t1) 58 self.threads.append(t2) 59 60 for t in self.threads: 61 t.setDaemon(True) 62 t.start() 63 64 while True: 65 pass 66 67 68 if __name__ == "__main__": 69 demo = ChatRoomPlus() 70 demo.start()