这篇文章主要讲解了“Python网络编程UDP协议分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python网络编程UDP协议分析”吧!
UDP协议——User Datagram Protocol,即用户数据包协议,UDP协议是无连接、不可靠、高效率数据传输协议。
UDP协议优点:开销小、速度快、无连接。
UDP协议缺点:无确认重传和排序、无流控制、无错误恢复。
UDP协议是面向报文的传输协议,它对报文既不拆分也不合并,而是给报文添加头部后就向下交给IP层。发现错误时不要重传,只是简单地把错误的报文扔掉、或给应用程序提供警告。
UDP协议广泛运用在强调数据传输速率的多媒体应用领域,例如网络聊天、在线视频、网络游戏、实时监控、路由协议中修改路由表等。
TCP协议遇到丢包或错误时要求重传,因而导致传输速率大幅降低。
UDP协议遇到丢包或错误时不要求重传,因为一个报文丢失后几秒内会有新的报文替代它,所以UDP协议传输速率比TCP协议高很多。
应用程序需要根据需要自定义应用层协议来处理报文丢失、错误、失序的情况。
编写UDP应用程序需要审慎考虑合适的报文长度:
局域网最大传输单元(Maximum Transmission Unit,MTU)默认是1500字节。
UDP协议头部是8字节、IP层协议头部是20字节。
单条报文建议长度是1024字节,最大长度不得超过65507字节(报文加头部总长不得超过65535字节)。
网络环境较好时报文长度及接收缓存建议设大一些,可以减少报文接收不及时导致丢包的概率。
创建socket实例。
sk = socket.socket(type=socket.SOCK_DGRAM)
注意:type=socket.SOCK_DGRAM是指定关键字参数,不能“缺省type=”,该参数用来指定使用udp协议。
绑定ip和端口。
sk.bind(('127.0.0.1',9001))
说明:该方法有一个参数,类型是元组(元组的第一个元素是IP,第二个元素是端口)。无返回值。
从UDP客户端收报文。
message,addrress = sk.recvfrom(1024)
说明:该方法参数是接收消息长度。返回值是元组,元组第一项是消息,第二项是ip及端口。
发送报文给UDP客户端。
sk.sendto(message,address)
说明:该方法有二个参数,第一个参数是要发送的消息,必须是bytes型;第二个参数是元组(元组的第一个元素是IP,第二个元素是端口)。返回值是发送的字节数。
创建socket实例。
sk = socket.socket()
发报文给UDP服务端。
sk.sendto(message.encode(),('127.0.0.1',9001))
说明:该方法有二个参数,第一个参数是要发送的消息,必须是bytes型;第二个参数是元组(元组的第一个元素是IP,第二个元素是端口)。返回值是发送的字节数。
从UDP服务端收报文。
message = sk.recv(1024).decode()
说明:该方法参数是接收消息长度。返回值是消息。
服务端
import socket HOST = '127.0.0.1' # IP地址PORT = 50007 # 端口max_connect = 5def main():accounts = { }with socket.socket(type=socket.SOCK_DGRAM) as sk:sk.bind((HOST, PORT))while True:msg, address = sk.recvfrom(1024)rev = msg.decode().split('|||')accounts[rev[0]] = addressif rev[1] in accounts:sk.sendto(msg, accounts[rev[1]])if __name__ == "__main__":main()
说明:这个是UDP协议简易聊天室服务端模型,服务端接收到客户端发来的消息,会记录客户端的ip和端口以及账号,并更新到字典中。遇到发往目标账户的消息在字典中时,会将信息转发给目标账户,从而实现多人聊天功能。
注意:代码目前没有缓存消息,当要发送的目标不在线时,该消息会被丢弃。
客户端
import socketfrom threading import Threadimport sys HOST = '127.0.0.1' # IP地址PORT = 50007 # 端口class Transceiver:def __init__(self, conn, server, account: str, target: str, buffer: int = 1024) -> None:self.conn = conn # socket实例self.server = server # 目标ip及端口self.buffer = buffer # 缓存区大小self.path = (account + '|||' + target + '|||').encode() # 己方账号def send(self, message: str) -> None:"""发送消息"""if type(message) is str: # 判断消息类型message = message.encode() # 将消息转成bytes型,缺省参数是utf8编码self.conn.sendto(self.path + message, self.server) # 发送消息def recv(self):"""接收消息"""message, _ = self.conn.recvfrom(self.buffer)message = message.decode('utf8').split('|||')return message[1], message[2] # 返回消息字符串def main():def send(m, message):m.send(message)def recv(m):while True:try:source, data = m.recv()print(f'收到"{source}"发来的信息:{data}')except:passwith socket.socket(type=socket.SOCK_DGRAM) as sk:account = input("请输入你的账号:")target = input("请输入你想聊天的账号:")m = Transceiver(sk, (HOST, PORT), account, target)t = Thread(target=recv, args=(m,))t.setDaemon(True)t.start()while True:message = input('请输入你要发送的信息:')if not message:continueif message == 'q' or message == 'Q':sys.exit(0)Thread(target=send, args=(m, message)).start()if __name__ == "__main__":main()
说明:这个是udp协议简易聊天室客户端模型,客户端登录时首先输入自己的账号和对方的账号,然后进入循环,循环输入发给对方账号的消息,另开了子收获进程接受服务端转发来的消息。
感谢各位的阅读,以上就是“Python网络编程UDP协议分析”的内容了,经过本文的学习后,相信大家对Python网络编程UDP协议分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。