一、说明
本文主要使用socket.socket发送UDP广播来实现聊天室功能。
重点难点:理解UDP通讯流程、多线程、UDP广播收发等。
测试环境:Win10Python3.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()