UDP网络编程
一、优缺点
UDP : 无连接 (发送端无需确认接收端是否收到), 其主要用途为音视频和广播等
他是不可靠的网络传输协议, 容易丢数据包
优点:
1.无连接
2.资源开销小
3.传输速度快, 但容易丢包
4.udp每个数据包最大是64K
缺点:
1.传输数据不可靠,容易丢数据包
2.没有流量控制,当对方没有及时接收数据,发送方一直发送数据会导致缓冲区数据满了,电脑出现卡死情况,所有接收方需要及时接收数据。
二、套接字socket
socket(简称 套接字) 是进程间通信一个工具,它能实现把数据从一方传输到另外一方,完成不同电脑上进程之间的通信, 它好比数据的搬运工。
1. 安装网络调试助手
将安装包粘贴到桌面, 使用sudo dpkg -i xxx.deb 安装
如果安装过程中出现"锁"的错误, 使用sudo rm /var/lib/dpkg/lock
2.创建和关闭套接字
关闭: udp_socket.close()
3.绑定端口
udp_socket.bind((本地IP, 端口))
如果需要绑定本机系统所有的IP 本地IP参数填' '
三、类型转换
1.
2.
注意: 在解码时候使用编码方案和 编码时保持一致 # 编码 解码 方法原型 def encode(self, encoding='utf-8', errors='strict'): def decode(self, encoding='utf-8', errors='ignore'):
# 其中的encoding是指在解码编码过程中使用的编码格式,errors是指错误的处理方案。
strict:表示严格按照指定编解码方式进行编码和解码,如果编解码不成功则抛出异常
ignore:表示忽略编解码不成功的字符,如果编解码不成功程序不会抛出异常
四、UDP发收数据
1.发送数据
import socket # 1. 创建udp套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 2. 准备接收方的地址 # '192.168.1.103'表示目的ip地址 # 8080表示目的端口 dest_addr = ('192.168.1.103', 8080) # 注意 是元组,ip是字符串,端口是数字 # 3. 从键盘获取数据 send_data = input("请输入要发送的数据:") # 4. 发送数据到指定的电脑上的指定程序中 udp_socket.sendto(send_data.encode('utf-8'), dest_addr) # 5. 关闭套接字 udp_socket.close()
2.接收数据
import socket # 1. 创建udp套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 2. 准备接收方的地址 dest_addr = ('192.168.236.129', 8080) # 3. 从键盘获取数据 send_data = input("请输入要发送的数据:") # 4. 发送数据到指定的电脑上 udp_socket.sendto(send_data.encode('utf-8'), dest_addr) # 5. 等待接收对方发送的数据 recv_data = udp_socket.recvfrom(1024) # 1024表示本次接收的最大字节数 # 6. 显示对方发送的数据 # 接收到的数据recv_data是一个元组 # 第1个元素是对方发送的数据 # 第2个元素是对方的ip和端口 print(recv_data[0].decode('gbk')) print(recv_data[1]) # 7. 关闭套接字 udp_socket.close()
五、广播和聊天器案例
1.UDP发送广播消息
import socket # 套接字通信 # 创建udpsocket udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 设置socket的选项,允许发送广播消息 udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True) # 发送广播消息 udp_socket.sendto("大家好,我叫小yang同学,多多关照!".encode(), ("192.168.33.255", 8080)) # 关闭socket udp_socket.close()
2.UDP聊天器
import socket def send_message(udp_socket): """发送消息""" # 需要用户数输入数据 IP 端口 data = input("数据:") IP = input("IP:") port = int(input("端口:")) udp_socket.sendto(data.encode(), (IP, port)) def recv_message(udp_socket): """接受消息""" res_data, addr = udp_socket.recvfrom(1024) print("用户%s传入的数据为:%s" % (str(addr), res_data.decode('gbk'))) def main(): # 1.创建UDP套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.bind(('', 9999)) # 2.开始循环接受用户输入,1:发送 2:接受 3:退出; 其他重新输入 while True: op = input("1.发送数据 2.接受数据 3.退出 请选择:") if op == '1': send_message(udp_socket) elif op == '2': recv_message(udp_socket) elif op == '3': print('buy') break else: print("输出有误,重新输入") # 3.退出循环才关闭 udp_socket.close() if __name__ == '__main__': main()