参考文章
代码
import time, socket, threading, os
from tkinter import *
'''
当TTL的值为 0 时,指定数据报应停留在本地主机中;
当TTL的值为 1 时,指定将数据报发送到本地局域网中;
当TTL 的值为 32 时,意味着只能将数据报发送到本站点的网络上;
当TTL 的值为 64 时,意味着数据报应被保留在本地区;
当TTL 的值为 128 时,意味着数据报应被保留在本大洲;
当TTL 的值为 255 时,意味着数据报可被发送到所有地方;
'''
roomnummap = {
'1': '230.1.1.1',
'2': '230.1.1.2',
'3': '230.1.1.3',
'4': '230.1.1.4'
}
myname = socket.getfqdn(socket.gethostname())
myaddr = socket.gethostbyname(myname)
# 定义本机IP地址
SENDERIP = myaddr
# 定义本地端口
SENDERPORT = 30000
# 定义本程序的多点广播IP地址
MYGROUP = '230.1.1.1'
# 通过type属性指定创建基于UDP协议的socket
s = socket.socket(type=socket.SOCK_DGRAM)
# 将该socket绑定到0.0.0.0的虚拟IP
s.bind(('0.0.0.0', SENDERPORT)) # ①
# 设置广播消息的TTL(Time-To-Live) 64 本地局域网
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 64)
# 设置允许多点广播使用相同的端口
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 将socket进入广播组
status = s.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(MYGROUP) + socket.inet_aton(SENDERIP))
# 这样可以切换多播组相当于切换聊天室 未实现
def changeGroup(num):
group = roomnummap[num]
print(group)
def sendmsg():
name=l2["text"]+":"
msg=name+str(inp2.get('0.0',END)).strip()
s.sendto(msg.encode('utf-8'), (MYGROUP, SENDERPORT))
inp2.delete('0.0',END)
# GUI设置
def changename():
myaddr = str(t1.get())
t1.delete(0,END)
l2.config(text=myaddr)
window = Tk()
window.title('网络聊天室')
window.geometry('720x600')
window.resizable(False, False)
frame = Frame(window, bg='white')
frame.place(x=0, y=0, width=720, height=300, relx=0, rely=0)
frame2 = Frame(window)
frame2.place(x=0, y=300, width=720, height=300, relx=0, rely=0)
scroll1 = Scrollbar(frame)
scroll1.pack(side=RIGHT, fill=Y)
inp1 = Text(frame, font=26, yscrollcommand=scroll1.set)
inp1.pack(fill=BOTH, expand=YES)
l1 = Label(frame2,text='设置名字否则是ip')
l1.pack()
t1 = Entry(frame2)
t1.pack()
l2 = Label(frame2,text=myaddr)
l2.pack()
# inp1.config(state=NORMAL)
bt2 = Button(frame2,text='设置',command=changename)
bt2.pack()
##inp1.config(state=DISABLED)
scroll1.config(command=inp1.yview)
inp2 = Text(frame2, height=5, font=26)
inp2.pack()
bt1 = Button(frame2, text='发送消息',command=sendmsg)
bt1.pack()
# 以read_socket作为target启动线程
def read_socket():
while True:
data = s.recv(2048).decode('utf-8')
position = data.index(":")
name =data[0:position]
msg = data[position+1:]
inp1.config(state=NORMAL)
inp1.insert(END,name+'('+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))+')'+ ": "+msg+"\n")
inp1.config(state=DISABLED)
# 定义从socket读取数据的方法
threading.Thread(target=read_socket).start()
window.mainloop()
图片如下