[Python] socket发送UDP广播实现聊天室功能

一、说明

  本文主要使用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()

 

posted @ 2018-11-24 12:33  蜗牛噢  阅读(4861)  评论(0编辑  收藏  举报