Python 基于UDP多播的网络聊天室

参考文章

参考文章1

参考文章2

参考文章3

代码

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()

图片如下
在这里插入图片描述

发布了22 篇原创文章 · 获赞 2 · 访问量 881

猜你喜欢

转载自blog.csdn.net/weixin_41685373/article/details/103779354