udp如何实现可靠性传输

TCP/UDP应用场景分析

游戏行业(可以让业务定制化,比如自定义重传策略,有些包可以不需要重发)、音视频通话(比如超过1s的包可以不重发)、出于资源的考虑,比如dns解析,手机定位获取隐私,嵌入式设备发送信息(用电池的设备,比如家里的消防传感器,一个电池用5年)、大块数据下载,不考虑网络拥塞。
tcp相比于udp,主要是重发导致的延迟。

UDP sendto/recvfrom的坑

tcp时流式传输,而udp是报文传输,发完的数据需要对端一次性读取完整,否则会造成数据丢失,所以一次性最多只能发送1500-20-8=1472的数据量(1500为网卡MTU的大小),避免拆包,加上PPPOE的协议头,一般发送1400就够了,在游戏领域,由于发送的数据量少,一般为572或者500就行了,如果发超过了,tcpdump可以看到会报bad length。

UDP如何实现可靠性设计

先要理解TCP传输协议,丢包怎么处理?什么情况下重传数据?怎么确认数据?对方没有回应数据包收到,超时重传。怎么处理包的先后顺序问题?重排机制。拥塞控制怎么实现?
有tcp可靠,为什么还要搞udp可靠?主要是可控:重传时间可控;业务认为过时的数据可以丢弃。
tcp协议头包括:16位源端口号、16位目的端口、32位序号、32位确认序号等,这里是有序号和确认序号的,可以确认数据和重拍数据,注意传输层没有ip。

udp协议头里面只有8个字节:16位的源端口、16位的目的端口、16位的长度和16位的校验和,要实现可靠性传输的话,还需要加同步字(比如0xff 0xfe)、所有分片数据的总大小(便于接收方提前分配好接受数据的内存)、分片数量、分片编号、该分片数据的大小等字段,需要将其放在udp的数据中。类似kcp还有会话id conv,这样重换网络后服务端还知道是原来的客户端,服务端收到包后,先解析convid是否已经注册过?如果没有注册过,把所有的数据都丢掉。否则解析账号密码校验,生成唯一的convid,服务端需要保存这个id。
接受数据方处理数据时检测同步字、解析数据总大小、需要根据编号放入对应的位置,这样就实现了重排。

nephen wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!