Discuss / Python / 一个简单的UDP聊天室,服务器是我自己的tx云,感兴趣的小伙伴可以开两个客户端自言自语玩。。。

一个简单的UDP聊天室,服务器是我自己的tx云,感兴趣的小伙伴可以开两个客户端自言自语玩。。。

Topic source

# 服务器端因为有公网ip,用作消息广播

import socket

s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

s.bind(('10.0.4.11',10028))

addr_user=[]

while True:

    msg,addr=s.recvfrom(1024)    # 收到的消息和客户端的地址

    if addr not in addr_user:

        addr_user.append(addr)

    print(addr_user)

    for a in addr_user:

        s.sendto(msg,a)

# 客户端

import socket,threading,random

s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

s.bind(('192.168.1.6',random.randint(10038,10050)))

user=input('请输入昵称')

ser_addr=('81.68.198.46',10028)

msg=''

def send_msg():     # 发消息

    while True:

        msg = input('')

        s.sendto(('%s:%s' % (user, msg)).encode('utf-8'), ser_addr)

def recv_msg():   # 刷新聊天室消息

    while True:

        print(s.recv(1024).decode('utf-8'))

send_msg=threading.Thread(target=send_msg)     # 发消息线程

recv_msg=threading.Thread(target=recv_msg)      # 刷新聊天室线程

send_msg.start()

recv_msg.start()

客户端运行结果如下:

请输入昵称小Q

你好呀

小Q:你好呀

在吗

小Q:在吗

小懒:我在

听不到

小Q:听不到

嗨呀

小Q:嗨呀

收到请回复

小Q:收到请回复

小懒:?

偶尔收不到

小Q:偶尔收不到

小懒:udp嘛,正常现象

发现一个bug,如果一个客户端好久没发消息,那么它将收不到其他客户端的消息。想到python的多线程不是并行执行,那么在刷新聊天室消息print(s.recv(1024).decode('utf-8'))这一步就有可能会卡壳

发现,并不是多线程的问题,在内网测试没有问题,这次的猜测是,在公网的服务器转发数据给一个好久没有发消息的客户端,这个客户端的地址和我网关的公网地址映射失效了。只有在我用这个客户端发一个消息给服务器,又会重新建立映射

发现2,可以让客户端每隔几秒发一条消息给服务端保持本地端口到公网端口的映射不消失(这里感觉可以用建立一个tcp连接来代替)


  • 1

Reply