UDP协议和黏包

Posted dymlnet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UDP协议和黏包相关的知识,希望对你有一定的参考价值。

udp是无链接的,先启动哪一端都不会报错

模板

import socket
udp_sk = socket.socket(type=socket.SOCK_DGRAM)   #创建一个服务器的套接字
udp_sk.bind((127.0.0.1,9000))        #绑定服务器套接字
msg,addr = udp_sk.recvfrom(1024)
print(msg)
udp_sk.sendto(bhi,addr)                 # 对话(接收与发送)
udp_sk.close()                         # 关闭服务器套接字

服务器端

import socket
ip_port=(127.0.0.1,9000)
udp_sk=socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(bhello,ip_port)
back_msg,addr=udp_sk.recvfrom(1024)
print(back_msg.decode(utf-8),addr)

客户端

 

ip协议属于网络osi七层协议中的网络层

TCP,UDP        传输层

arp            数据链路层

 

socket参数的详解

socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)

技术分享图片

 

 

黏包

tcp协议的拆包机制

当发送端缓冲区的长度大于网卡的MTU时,tcp会将这次发送的数据拆成几个数据包发送出去。 
MTU是Maximum Transmission Unit的缩写。意思是网络上传送的最大数据包。MTU的单位是字节。 
大部分网络设备的MTU都是1500。如果本机的MTU比网关的MTU大,大的数据包就会被拆开来传送,这样会产生很多数据包碎片,增加丢包率,降低网络速度。
TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务。
收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,
使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。 这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 即面向流的通信是无消息保护边界的。 对于空消息:tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,
而udp是基于数据报的,即便是你输入的是空内容(直接回车),也可以被发送,udp协议会帮你封装上消息头发送过去。 可靠黏包的tcp协议:tcp的协议数据不会丢,没有收完包,下次接收,会继续上次继续接收,己端总是在收到ack时才会清除缓冲区内容。数据是可靠的,但是会粘包。

例如基于tcp的套接字客户端往服务端上传文件,发送时文件内容是按照一段一段的字节流发送的,在接收方看了,根本不知道该文件的字节流从何处开始,在何处结束

此外,发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段。若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据。

技术分享图片

 




以上是关于UDP协议和黏包的主要内容,如果未能解决你的问题,请参考以下文章

TCP协议和UDP协议

通俗地解释一下 TCP/UDP 协议和 HTTPFTPSMTP 协议之间区别

MQTT协议和TCP协议有啥区别?为啥人们推荐MQTT协议?

UDP协议和TCP协议的区别?

TCP协议和UDP协议

TCP协议和UDP协议