Python UDP编程基础与实践

UDP(User Datagram Protocol,用户数据报协议)是一种无连接的、不可靠的、基于数据报的传输层协议,它不保证数据的可靠传输,但具有较高的传输速度和较低的延迟,在实际应用中,UDP常用于实时音视频通信、在线游戏、DNS查询等场景,本文将介绍Python中UDP编程的基本知识与实践。

Python UDP编程基本知识

1、socket模块

Python中的socket模块提供了对网络套接字的支持,包括TCP和UDP套接字,要使用socket模块进行UDP编程,首先需要导入socket模块,然后创建一个UDP套接字对象。

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

2、bind()方法

bind()方法用于将套接字绑定到一个地址和端口上,在进行数据传输之前,需要先绑定一个地址和端口。

server_address = ('localhost', 10000)
sock.bind(server_address)

3、recvfrom()方法

recvfrom()方法用于接收客户端发送的数据,它接收两个参数:最大字节数和地址信息,返回值是一个包含数据和客户端地址的元组。

data, client_address = sock.recvfrom(1024)

4、sendto()方法

sendto()方法用于向指定的客户端发送数据,它接收两个参数:要发送的数据和客户端地址。

sock.sendto(data, client_address)

5、close()方法

close()方法用于关闭套接字,在完成数据传输后,需要关闭套接字以释放资源。

sock.close()

Python UDP编程实践

下面通过一个简单的UDP回显服务器和客户端的例子来演示Python UDP编程的实践。

pythonudp python udp通信

1、创建UDP回显服务器

import socket
import threading
def handle_client(sock, client_address):
    while True:
        data, addr = sock.recvfrom(1024)
        print(f"Received from {addr}: {data.decode('utf-8')}")
        sock.sendto(data, addr)
def main():
    server_address = ('localhost', 10000)
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(server_address)
    print(f"Server started at {server_address}")
    sock.settimeout(5)  # 设置超时时间,防止死循环
    while True:
        try:
            client_address = sock.getpeername()  # 获取客户端地址信息
            threading.Thread(target=handle_client, args=(sock, client_address)).start()  # 创建线程处理客户端请求
        except socket.timeout:  # 超时,继续等待下一个客户端请求
            continue
        except Exception as e:  # 其他异常,打印错误信息并退出程序
            print(f"Error: {e}")
            break
    sock.close()
    print("Server closed")
if __name__ == "__main__":
    main()

2、创建UDP回显客户端

import socket
import threading
import time
import random
import string
def send_data():
    while True:
        data = ''.join(random.choices(string.ascii_letters + string.digits, k=10))  # 生成随机字符串作为数据发送给服务器
        sock.sendto(data.encode('utf-8'), server_address)  # 发送数据到服务器,并接收服务器的回显数据
        print(f"Sent to server: {data}")
        time.sleep(random.uniform(0.5, 2))  # 随机等待一段时间再发送下一个数据包,模拟实际网络环境的变化情况
        received_data, server_address = sock.recvfrom(1024)  # 接收服务器回显的数据包,并获取服务器地址信息,这里不需要处理异常情况,因为已经设置了超时时间,如果超时则会继续等待下一个数据包的到来,因此不会阻塞在这里。        print(f"Received from server: {received_data.decode('utf-8')}")        print(f"Server address: {server_address}")        print("=" * 40)        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        print()        time.sleep(random.uniform(0.5, 2))    # 随机等待一段时间再发送下一个数据包,模拟实际网络环境的变化情况    # print("=" * 40)    # print("Client is running...")    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" * 40)    # print("=" *