传输层: UDP 与 TCP协议

本文详细介绍了UDP和TCP协议的格式、特性及它们在网络通信中的作用。UDP是无连接、不可靠的数据报协议,适合实时传输,而TCP是面向连接、可靠的字节流协议,提供顺序传输和错误检测。TCP通过三次握手和四次挥手建立和终止连接,采用滑动窗口、拥塞控制等机制保证数据可靠性。同时,文章还讨论了TCP的保活机制和如何处理异常情况。
摘要由CSDN通过智能技术生成

目录

UDP协议:

udp协议格式(实现):

udp协议特性:

影响:

TCP协议: 

TCP格式(实现):

协议特性: 

面向连接: 

****tcp连接管理的过程(三次握手四次挥手): 

可靠传输: 

****传输性能提升各种机制:

面向字节流**: 

tcp连接管理中的保活机制:


可以说应用层负责规定应用程序之间沟通的方式. 那传输层负责数据能够(准确的)从指定源端口发送到指定对端口.

UDP协议:

用户数据包协议.

udp协议格式(实现):

16位源端端口: 描述源端处理进程是谁. 16位对端端口: 描述对端处理进程是谁,源端与对端端口描述了是哪两个进程之间在进行传输

16位数据报长度: 即报文长度, 为报头长度+实际数据长度,所以实际的数据长度是报文长度减8;
因为udp协议限制了报文最大不超过64k. 则报文中数据大小(上层所sendto给予的大小)必须小于64k-8。否则就会丢弃数据报错

16位校验和: 采用二进制反码求和算法,校验收到的数据与对方发送的数据是否完全一致,不一致则丢弃.

二进制反码求和算法: 发送方组织好报文后,将校验和字段置为0,然后从第0个字节开始(包含报头)对每个字节取反求和,超出16位的,则将高位截断与低16位继续求和,完成之后,将校验和填充到校验和字段中接收方收到数据,从头到尾进行反码求和,这时候如果数据没问题,则刚好得到的结果就是0.
 

udp协议特性:

无连接: 指只要知道对方的地址就能给对方发送数据, 不需要建立连接.

不可靠: udp没有任何的丢包检测机制,数据包丢了也没有重传机制,并且也没有包序管理机制
因此udp传输既不保证数据能够安全到达对端,也不保证数据有序到达对端

面向数据报: 一种有最大长度限制的,数据块传输方式, 因为udp协议中限制了一个udp报文必须小于64k(数据必须小于64k-8)

数据块的传输方式: 上层sendto给与一个数据则直接封装报头进行发送,数据到达对端会包括报头存放在接收缓冲区中
上层recvfrom时候每次只能刚好取出一条完整数据,不能取出半条或者多条数据. 因为如果取出半条或者一条半,缓冲区中剩余半边数据,下次取的时候就不知道该取多少, 因此udp通信有一个严格点: 整条传输整条交付 意味着: recvfrom的时候如果你给的buf空间大小比接收的数据长度小则会接收失败.

影响:

1. udp不保证数据安全有序到达,需要程序员自己在应用层进行丢包检测以及包序管理机制以及重传机制,才能保证安全至少要在上层有包序管理。
2. udp面向数据报的,必须保证sendto发送的数据长度必须小于64k-8个字节大小
3. udp是整条交付的,必须保证recvfrom时,给与的空间大小足够大,否则有可能会接收失败

TCP协议: 

传输控制协议.

TCP格式(实现):

16位源端端口+16位对端端口: 描述通信两端
32位序号+32位确认序号: 实现tcp的包序管理,以及确认应答机制(丢包检测), 相当于tcp对数据都给予了序号, 接收端再根据序号进行排序.
4位报头长度: 描述tcp报头长度. 因为报头中的选项数据可有可无, 大小为0-40个字节, 所以报头长度最大是60字节,最小20字节, 在解析tcp报头时,先取出固定长度20字节,然后根据报头长度-20取出指定长度的选项数据,剩下应用数据
4位保留: 暂时没有使用
8位标志位: 用于标识报文类型. URG紧急指针有效位,ACK确认应答,PUSH描述尽快取出报文,RST重置连接,SYN建立连接请求,FIN断开连接请求.  RST: 当收到了非法请求,或者连接出现问题则向客户端端发送RST重置连接报文,要求客户端重新建立连接
16位窗口大小: 用于实现滑动窗口机制-进行流量控制-防止发送方发送数据过多
16位校验和: 校验接收到数据与发送的数据是否一致
16位紧急指针: 描述紧急数据(带外数据)的结束位置,正常数据的起始位置
0~40字节的选项数据: 不一定有,通常是一些协商信息或者保存一些额外数据的作用。
 

协议特性: 

面向连接: 

面向连接指的是通信前客户端要先向服务端发送连接请求. 

****tcp连接管理的过程(三次握手四次挥手): 

tcp是全双工通信, 即通信前需确认双方都具有收发数据的能力.

***握手为什么是三次?挥手是四次?
握手三次是因为两次不安全,四次没必要,两次不安全主要指的tcp全双工通信,需要双方都确认对方在线才能通信,而四次没必要主要是因为请求其实就是个标志位,SYN+ACK两个请求完全可以合为一个进行发送。挥手四次是因为FIN包的断开连接只能表示自己不再给对方发送数据了,不代表自己不接收数据,被动关闭方进行确认之后,还有可能会给主动关闭方发送数据,因此不会直接发送FIN,而是等待上层确认关闭连接不再发送数据的时候才会发送FIN包给主动关闭方
 

***三次握手失败两端是如何处理的?
客户端发送SYN失败: 服务端什么都没收到则什么都不做, 客户端会重传SYN请求.
服务端收到SYN回复SYN+ACK失败: 服务端并不会重传,客户端等待超时后会认为syn丢包,重传SYN客户端. 最后发送ACK失败: 服务端等待超时,则回复RST报文,然后释放刚新建的连接
SYN_RCVD状态就是等待ACK,收到到其他的请求则认为非法请求,回复RST
syn泛洪攻击-synflood:恶意主机伪造IP地址发送大量SYN请求不进行回复,占据服务端资源

断开连接不能以客户端和服务端来说, 以主动关闭方和被动关闭方, 因为服务端也能主动提出断开连接. 

***一台主机上出现大量的close_wait状态是什么原因?
closee_wait是被动关闭方收到FIN包进行确认回复之后,等待上层处理的状态,因此一台住上如果出现了大量连接处于close_wait,意味着有可能代码中在连接断开后,忘记进行close,也就是没有进行四次挥手的下一步操作
 

***time_wait有什么用?为什么主动关闭方已经进行了确认回复不释放套接字要等待一段时间?
假设没有time_wait状态,回复ack之后直接释放套接字,但是最后一次等待ack回复丢失了被动关闭方就会重传FIN, 这时候如果恰好主动关闭方启动了一个新的套接字,刚好使用之前释放的地址信息(和刚释放的套接字使用一样绑定的端口和ip),则这时候这个新连接什么都没干先收到了一个FIN包,这就不合理。包括新的套接字给服务器发送SYN请求,但是服务端处于LAST_ACK等待连接状态就会认为请求非法,这也不合理
总结: 如果没有time_wait直接释放套接字,有可能由于最后一次ack丢失导致的重传会对新连接造成影响, 有time_wait就可以在收到重传的fin包后重传ack.

***那time_wait等待多长时间比较合适呢?
等待时间是两个MSL(最大报文生成时间)时间 (可以理解给FIN和ACK两个重传的最大时间.)
time_wait作用就是等待2个msl时间,处理有可能因为最后一次ack丢失所导致的fin包重传,避免对后续新连接造成影响. msl默认通常是60秒

***一台主机上同一时间段出现大量time_wait状态什么原因,如何处理?
time_wait状态是主动关闭方,在进行最后一次ack之后进入的状态,意味着一台主机上出现了大量的time_wait, 原因就是这台主机上大量的主动关闭了套接字(close或shutdown,不是释放)。常见于爬虫服务器(创建大量的客户端去请求服务器然后关闭)   解决方案:
1.可以把time_wait等待时间调短一些
2.可以使用套接字选项,启动端口地址复用功能接口:
int setsockopt(int sockfd,int level,int optname, void *optval, int optlen)
level:选项等级- SOL_SOCKET
optname:选项名称- SO_REUSEADDR, int optval = 1;
setsockopt(sockfd, SoL_SOCKET,SO_REUSEADDR,&optval, sizeof(optval));

 

***time_wait到底是用来保护客户端的还是服务端?
time_wait说是用于保护主动关闭方,但是实际上更多是为了保护客户端,因为服务端通常需要绑定固定的地址端口,服务端反而因为time_wait的原因,在主动关闭后无法重新立即使用.


 

可靠传输: 

可靠传输即数据安全、有序地传到对端. 

****udp如何实现可靠传输? :

****传输性能提升各种机制:

TCP使用了很多实现可靠传输的机制, 影响了传输性能, 但有些性能没必要, 可以通过以下提升性能机制来提升 :

****延迟发送: 发送方延迟发送数据,因为每次发送数据都会涉及到硬件的操作,效率较低,如果在发送大量短小数据的时候就很不划算,因此延迟发送会把多个小数据在发送缓冲区中堆积成为一个大数据进行一次发送

****延迟应答机制: 因为接收方接收到数据后都会进行确认回复,如果立即进行回复,不可避免大概率窗口都会变小,则发送方的发送数据量就会变小,吞吐量小了,传输性能就低了,因此采用延迟应答,收到数据后不立即进行回复,而是等待一段时间,而这段时间内,上层就有可能将数据从缓冲区取出,则窗口大小会不变甚至变大,保持吞吐量.

****捎带应答机制: 接收方会为发送方发送的每个数据进行确认回复,而一个确认回复就是一个空报头(只有确认序号),而空报头的传输会导致占用带宽降低传输效率,如果这时候刚好要给对方发送数据,那就将这个确认回复和要发送的数据合在一起进行发送,毕竟确认回复只是一个头部信息,而这样可以提高传输效率

****快速重传机制: 如果发送的一个数据包丢了,发送方如果总是要等到超时才能重传,效率就较低,这时候采用快速重传机制效率就能得到提高。接收方接收数据的时候,接收到的数据不是从预期起始开始的,则认为前边的数据可能丢失了,则这时候回复前边预期起始序号的确认应答作为重传请求,并且间隔连续发送三次,这样就不用等超时,而是连续三次收到相同重传请求则对对应序号的数据进行重传。
三次是为了避免因为延迟而到达导致的重传,三次期间如果收到数据则而不满三条就不需要重传

****滑动窗口机制:

1.实现思想: 主要是基于协议字段中的窗口大小字段实现流量控制.否则发送方发送数据过多,而接收方上层获取太慢,导致接收方的接收缓冲区满了,则多出来的数据就会被丢弃,而丢弃的就会导致重传,效率降低。

接收方每接收一条数据就会进行确认应答,在确认应答的时候就会通过窗口大小字段告诉对方,最多在发送多少数据就不要发送了(这个窗口大小不会大于接收缓冲区的剩余空间大小),这样就可以避免因为发送数据过多而导致丢包的情况。

2.实现细节: 通信双方都会维护发送,接收两个窗口. 窗口有前沿和后沿之分.
发送窗口后沿: 发送的起始数据序号; 发送窗口前沿: 发送的数据结束序号

接收窗口后沿: 接收的起始数据序号; 接收窗口前沿: 接收的数据结束序号

发送窗口大小不会大于对方回复的窗口大小字段值: 前沿—(减)后沿<对方win大小

接收窗口大小不会大于缓冲区剩余空间大小: 前沿—后沿<剩余空间大小

3.滑动窗口机制中的特殊协议: 针对不同的网络状况有不同的选择---不同的适用场景

停等协议: 发送一条数据后,必须等收到确认应答才会发送下一条数据(网差的场景)

回退n步协议: 如果一条数据丢失,则会将从丢失数据序号开始之后数据都进行重传

选择重传协议: 哪条丢了,重传哪条
 

****拥塞机制: 如果发送数据过程中,网络状况突然变差,这时候发送的数据越多越快,则丢失的数据就越多,最终导致大量重传降低效率。拥塞机制是发送方所维护的一个机制(拥塞窗口-发送数据大小的限制)
拥塞窗口一开始很小,但是涨幅非常快(指数级的增长, 当然也会有个阈值即窗口大小),以这种形式进行网络探测, 一旦传输过程中出现丢包,则会重新开始拥塞控制.

 拥塞机制和滑动窗口机制都是为了避免额外多丢了包.

面向字节流**: 

优点: 字节流传输, 即不管是发送还是接收, 都可以以字节为单位, 想发、想收多少自定. 不需要像udp一样整条整条的数据交付.

缺点: 因为数据可以在缓冲区堆积会存在tcp粘包问题, 将不同的多条数据当同一条处理.

解决粘包(上层编程时):

1. 以特殊字符作为数据头或者数据尾,间隔多条数据(比如http的做法,头部以\rln\rln作为结尾)
缺陷是如果数据本身就有特殊字符,则需要做转义处理.
2. 固定数据长度,设置足够长度,数据不够则补位.
缺陷是有补位则性能低,因为传输的数据多了. 如果有超长数据也麻烦.
3. 使用TLV格式数据,每个数据有个固定长度的应用层头部,头部中定义了数据长度(udp、http的做法)先取出头部,然后根据头部中的数据长度,取出剩余的数据(所以udp整条交付有边界管理, 没有粘包问题.)

tcp连接管理中的保活机制:

如果tcp在传输过程中,网络中断,而自己有很长时间没有发送数据,则不知道连接已经断开,套接字实际上没用了,但是依然占据资源。
因此tcp具有连接保活机制,服务器在长时间没有数据通信时(默认7200s),则间隔一定时间(75s)发送-个保活探测数据包给对方,如果多次没有收到探测响应(9次),则认为连接断开,释放资源。
如果觉得太慢影响效率, 这些默认数据都是可配置的,并且通过设置套接字选项操作( setsockopt()接口) 就可以进行单独设置.

如果连接断开,在程序中是如何体现的?(程序中如何感知连接断开)
连接断开,则recv接收完数据之后,继续recv则不再阻塞,而是返回0;(recv返回0就是连接断开)如果是send,则在连接断开后,会触发异常(SIGPIPE),导致进程退出.如果不想因为连接断开而导致发送数据的时候程序异常退出,则需要对SIGPIPE信号进行自定义或者忽略处理.



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值