创建基于UDP的socket
# 基于网络的UDP
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
解决端口占用
# 解决端口占用问题
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
绑定ip和端口
# 绑定ip:port
sk.bind(('', 8080))
收发消息
收消息
sk.recvfrom()
,返回一个元组,[0]
是具体的内容,bytes
;[1]
是客户端地址。
关于recvfrom()
的注意事项:
-
在
unix
系列操作系统中,
如果sendto()
发送的数据大小大于recvfrom()
接收的大小,那么按recvfrom()
最大限度接收,剩下的直接丢弃。 -
在
windows
操作系统中:
如果sendto()
发送的数据大小大于recvfrom()
接收的大小,则直接抛出异常OSError
msg, addr = sk.recvfrom(5)
发消息
sk.sendto()
sk.sendto(msg + b'_Python', addr)
Server端代码
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""UDP
Server端
UDP
1. 面向无连接的、不可靠的、不安全的,有消息保护边界
2. UDP服务端一开始只能被动接收(因为没有连接啊)
3. 基于UDP通信,先启动谁都没关系,因为UDP通信的sendto不用管这个地址是否真实存在,只管一个劲的发送,只是数据会丢失而已
4. UDP又称数据报协议,以消息为单位,每一次发送为一次消息,接收端也只接收这一次
所以不会发生黏包。如果想要接收到消息recvfrom和sendto要对应。
5. UDP可以发送空消息,但实际上不是空消息,因为还有UDP头
6. UDP数据部分最大 = 65535 - 20(IP头) - 8(UPD头) = 65507
关于recvfrom()的注意事项:
1. 在unix系列操作系统中,
如果sendto()发送的数据大小大于recvfrom()接收的大小,那么按recvfrom()最大限度接收,剩下的直接丢弃
2. 在windows操作系统中:
如果sendto()发送的数据大小大于recvfrom()接收的大小,则直接抛出异常OSError
"""
import socket
# 基于网络的UDP
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
# 解决端口占用问题
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip:port
sk.bind(('', 8080))
while 1:
try:
msg, addr = sk.recvfrom(5)
if msg == b'exit':
sk.sendto(msg, addr)
break
print(msg.decode(encoding='utf-8'))
sk.sendto(msg + b'_Python', addr)
except OSError as e:
print(e)
break
sk.close()
Client端代码
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""UDP
Client端
"""
import socket
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
ip_port = ('localhost', 8080)
while 1:
try:
msg = input('>>> ').strip()
sk.sendto(msg.encode(encoding='utf-8'), ip_port)
msg, addr = sk.recvfrom(5)
if msg == b'exit':
break
print(msg.decode(encoding='utf-8'))
except OSError as e:
print(e)
break
sk.close()
UDP其他说明
- 面向无连接的、不可靠的、不安全的,有消息保护边界。
- UDP服务端一开始只能被动接收(因为没有连接呀)。
- 基于UDP通信,先启动谁都没关系,因为UDP通信的
sendto
不用管这个地址是否真实存在,只管一个劲的发送,只是数据会丢失而已。 - UDP又称数据报协议,以消息为单位,每一次发送为一次消息,接收端也只接收这一次,所以不会发生黏包。如果想要接收到消息
recvfrom
和sendto
要对应。 - UDP可以发送空消息,但实际上不是空消息,因为还有UDP头
- UDP数据部分最大 = 65535 - 20(IP头) - 8(UPD头) = 65507