基于python的udp聊天器案例
代码实现
功能分析, 发送消息, 接收消息, 退出
import socket
def send_msg(udp_socket, dest_ip, dest_port):
"""发送消息"""
# 获取发送消息
send_data = input("请输入要发送的消息: ")
udp_socket.sendto(send_data.encode("utf-8"), (dest_ip, dest_port))
def rec_msg(udp_socket):
"""接收数据"""
rec_data = udp_socket.recvfrom(1024)
print(str(rec_data[1]) + rec_data[0].decode("utf-8"))
def main():
# 创建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定信息
udp_socket.bind(("", 8888))
send_init = False # 发送数据前绑定ip, 端口
# 程序控制
while True:
op = input("请输入操作码: 1:发送消息, 2:接收消息, 0退出\n")
if op == "1":
if not send_init:
print("正在初始化发送信息...")
dest_ip = input("请输入对方ip: ")
dest_port = int(input("请输入对方端口: "))
send_init = True
send_msg(udp_socket, dest_ip, dest_port)
elif op == "2":
rec_msg(udp_socket)
elif op == "0":
break
else:
print("输入错误, 请重新输入...")
if __name__ == '__main__':
main()
复制2份上述代码, 两份代码给予不同的端口, 如8888, 9999, 运行这两个程序, 即可实现简单的udp聊天
注: 公网无法发送给客户端, 因为客户端通信是靠运营商代理服务器分配的临时端口, 可能10秒无连接就关闭了, 再次发送就会更换, 客户端无法绑定端口( 而且似乎收不到数据, 只能发), 就理论上来说, udp通信必须知道客户端ip和端口, 而像qq这样的用纯udp很难实现, 需要tcp辅助
( 如果代理的临时ip, 端口可以接收udp数据并送回客户端, 是可以实现的, 每隔10秒发一条数据到服务器, 以不断更新临时端口, 但这样也太过麻烦了, 有一种可行但不通用的办法是”端口映射”, 仍无法从根本上解决问题)
udp特点讲解
udp是一种经典的邮件模型, 具有以下特点
- 如果8888端口发送给9999, 对方未开启此端口, 则数据被操作系统丢弃
- 如果8888端口发送给9999, 对方开启了此端口, 则数据被操作系统缓存, 当9999程序接收时, 从操作系统缓冲区取走
可以发现, 数据可能会丢失, 而且可能遭受攻击
ps: 如果你开启了某个端口( 启用了udp协议 ), 若有人恶意发送大量数据给此端口, 而程序没有及时接收完(需循环接收),以操作系统来之不拒的特点, 很快系统缓冲区就会爆满(内存), 然后机器会很卡, 正常的消息也无法接收到了。在服务器维护中, 对于不使用的端口, 最好是关闭