UDP协议没有粘包问题,但是缓冲区大小要足够装数据包大小,建议不要超过 512
服务端:
# 服务端import socketserver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议-》udpserver.bind(('127.0.0.1', 8080))# OSError: 一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。data, client_addr = server.recvfrom(1) # b'hello' ==> b'h'print('第一次:', client_addr, data)data, client_addr = server.recvfrom(1024) # b'world' ==> b'world'print('第二次:', client_addr, data)# data, client_addr = server.recvfrom(1024)# print('第三次: ', client_addr, data)server.close()
客户端:
# 客户端import socketclient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 数据报协议 ==> UDP协议client.sendto('hello'.encode('utf-8'), ('127.0.0.1', 8080))client.sendto('world'.encode('utf-8'), ('127.0.0.1', 8080))# client.sendto(''.encode('utf-8'), ('127.0.0.1',8080))client.close()
基于UDP协议通信的套接字
服务器:
1)创建套接字描述符(socket)2)设置服务器的 IP 地址和端口号(需要转换为网络字节序的格式)3)将套接字描述符绑定到服务器地址(bind)4)从套接字描述符读取来自客户端的请求并取得客户端的地址(recvfrom)5)向套接字描述符写入应答并发送给客户端(sendto)6)回到第 4 步等待读取下一个来自客户端的请求客户端:
1)创建套接字描述符(socket)2)设置服务器的 IP 地址和端口号(需要转换为网络字节序的格式)3)向套接字描述符写入请求并发送给服务器(sendto)4)从套接字描述符读取来自服务器的应答(recvfrom)5)关闭套接字描述符(close)服务端:
# 服务端import socketserver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)server.bind(("127.0.0.1", 8080))while True: data,client_addr = server.recvfrom(1024) print(data.decode("utf-8")) server.sendto(data.upper(), client_addr)server.close()
客户端:
# 客户端import socketclient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)while True: msg = input("请发送: ").strip() client.sendto(msg.encode("utf-8"), ("127.0.0.1", 8080)) data, server_addr = client.recvfrom(1024) print(data.decode("utf-8"))
对于 UDP 协议,客户端发送空没有问题,因为 UDP 协议又叫数据报协议,自带报头,在发送空的时候自动将报头信息发送过去,所以服务端也能接收数据。同时 UDP 协议可以同时处理多个客户端,是因为 CPU 的处理速度快,给人感觉像是在同时处理