tcp

面向连接,点对点,可靠交付,全双工通信,面向字节流(太长可拆,太短可等)
tcp连接的端点是套接字socket=ip+port
一般情况我们如何实现可靠传输:
确认,超时重传,重传时间长于平均往返时间,收到重复数据直接丢弃数据并再次ack(ack丢了),收到重复ack无视之(ack路上耽搁太久,我早就重传且收到ack了),流水线传输(不要发了就等ack,这样信道利用率低,可以连续发送多个分组),累积确认(不必收到一个分组就ack一次),捎带确认(有数据发的时候顺便ack),但不能过分推迟ack(否则引起超时重传,当然也影响对端发送窗口的前移)
在这里插入图片描述
序号用完了就回到0重新增加,起始序号连接建立设置
确认号为N,到序号N-1的数据都收到了,请传序号为N开始的数据
数据偏移:数据起始处的偏移,即指出首部长度,最大60
6控制位
为了理解urg和psh,做一定假设:
1 进程从接收缓存取SocketInputStream.read
2 主动交付/上推模式(缓存满了,psh数据来了交付psh数据和之前数据),我没见过,现在已经不需要将数据交付给应用层
URG:数据内含紧急数据,尽快传送,不按排队顺序,紧急指针指出紧急数据长度,紧急数据后为普通数据
1 发送端无视窗口限制,窗口为0也可以发,即紧急数据超出发送窗口也能发
2 接收端数据不入接收缓存,直接交付应用层,java socket.setOOBInline(true)后可以SocketInputStream.read读出
ACK:连接建立后,所有报文段ACK都为1, 没有ack no就不是确认
PSH:尽快交付给应用进程,发送端不等,比如由于包太小的等待,接收端在上推模式上快速交付
RST:表明出现差错,必须释放连接重新连接。拒绝非法报文段,拒绝连接,主机崩溃等
SYN和FIN
窗口:接收窗口
校验和:校验首部和数据
选项:如MSS(数据长度),MSS尽量大(传输效率),只要保证不分片,如1460,两个方向可以不同MSS,如在连接建立时A表明自己MSS1460,B不表明(默认536),那么以后A传数据按1460传,B按536传
TCP Window Scale 窗口扩大,接收窗口太大怎么办,握手时告知对方收到我的接收窗口请按移位值S进行扩大,真实窗口为窗口值左移S位(乘以2的S次方)
时间戳选项:计算RTT(发送方放入,接收方ack时带回)和 序号重用时用于区分
选择确认(Selective ACK,SACK ) 不管是超时还是快速重传都需要知道对端收到了哪些数据,以减少不必要的重传,连接建立时商议是否允许SACK(双方都发SACK_PERM=1),最多可指明4个字节块的边界(左边界seq no4字节,右边界4),4X8=32,还有2字节表明SACK选项和SACK选项占用长度,34小于40,否则5字节块就42了。

在这里插入图片描述在这里插入图片描述在这里插入图片描述

接收缓存含应用程序尚未读取的数据。
接收缓存=按序到达且ack + 接收窗口(按序达到未ack和未按序达到数据)
RTO(超时重传时间)=RTTs (加权平均往返时间)+ 4×RTTd(RTT的偏差的加权平均值)

流量控制:接收窗口rwnd,rwnd为0,停止发送,发出rwnd不为0,就可以继续发送,若rwnd不为0的报文丢失,造成死锁(发送端等rwnd不为0通知,接收端等数据),因此持续计时器:接收到rwnd为0,启动计时器,到期发出零窗口探测报文段,对方给出窗口,为0重新设置计时器,否则可发送数据。

Nagle算法:对于逐个字节加入发送缓存的怎么处理?先发第一个字节,收到ack发送缓存剩余字节,收到前一报文段ack才发下一报文段。当然数据积累到MSS或发送窗口一半,也立即发一报文段。

延迟确认:延迟一段时间ack以便捎带确认,当然超时后还是要ack

糊涂窗口综合症:对于逐个字节从接收缓存取的怎么处理?接收缓存满,取1字节,发1字节的rwnd(ack报文),发送方发来1字节
接收方等待到接收缓存有1MSS空间或一半空闲空间,再ack(此时通知的rwnd够大)

拥塞控制:
拥塞:对资源需求大于可用资源,网络性能变坏,吞吐量随输入负荷增大而下降
拥塞一般是多因素问题,随意加些资源没用,比如增加节点(路由器)缓存,导致原来丢弃的现在排队,导致超时重传,更多数据流入网络,反而加剧拥塞
拥塞实质是系统各部分不匹配,需保持各部分平衡
拥塞控制:防止过多数据注入网络。流量控制:点对点通信量控制,接收端控制发送端
在这里插入图片描述
理想:45度斜线,输入网络的分组(负载)和从网络输出的分组(吞吐量)一样
无拥塞控制:网络未饱和就已经有分组丢弃了,吞吐量明显小于理想吞吐量,进入轻度拥塞,提高负载吞吐量反而下降时,进入拥塞,下降到零,死锁
实际的拥塞控制:有丢弃,但平缓上升。
拥塞控制的方法:
慢开始,拥塞避免,快(速)重传,快恢复
在这里插入图片描述
发送方维护拥塞窗口cwnd
cwnd开始为1MSS(慢开始), 每收到一个对新报文段的确认,cwnd加1MSS,每个传输轮次(把发送窗口所有数据都发出,并收到所有确认,基本为RTT)cwnd翻倍,上图横轴为传输轮次
以上有些理想处理:发送窗口为拥塞窗口(接收窗口不限制),发送窗口数据连续发送,累积确认导致拥塞窗口增长变慢(慢开始:1ack增长1MSS,拥塞避免:1ack增长1/n MSS,n为拥塞窗口大小)
举例:如现处于慢开始阶段,拥塞窗口为10,发送窗口为8,发送窗口内含数据量为6,RTT50,传输轮次计算出为56(50+6x1,发送1MSS需消耗时间1),接收到6MSS仅发回3ack(累积确认),理论:50的时间增长了10MSS,实际:56的时间增长了3MSS
增长到慢开始门限(ssthresh),一个传输轮次(基本RTT)cwnd增加1MSS(拥塞避免,加法增大)
发送方认为拥塞(即发生超时重传,可能实际并没有拥塞,可出现在慢开始和拥塞避免阶段),ssthresh设为此时拥塞窗口一半(乘法减小),cwnd设为1,重新慢开始
上图修正:12发出数据,经过RTO超时重传,所以不是在13而是12+RTO时cwnd设为1,RTO内无数据传输且cwnd为1导致超时重传严重影响性能。
在这里插入图片描述

收到3dup ack,共四个相同ack,快速重传(不用等到超时再重传),此时认为网络很可能没有拥塞(否则后面的数据不可能都到了),乘法减小,并拥塞窗口设为新的ssthresh,执行拥塞避免(快恢复)
发送窗口为接收窗口和拥塞窗口的较小那个。
随机早期检测RED
路由器 若使用尾部丢弃策略:队列满了,后面来的全部丢弃,导致多个连接超时重传,全部慢开始(全局同步),通信量突降很多,考虑提前丢弃一些分组,避免尾部丢弃
路由器使用RED: 平均队列长度,最小门限,最大门限
平均队列长度小于最小门限,排队
两者之间,按概率丢弃
大于最大门限,丢弃
在这里插入图片描述
服务器创建传输控制块TCB,处于listen状态,第三次ack可带数据(有序号且消耗序号)也可不带数据(有序号但不消耗序号,下个序号依然x+1)
为什么要三次握手:A连接请求丢失,A重传连接请求,建立连接
A连接请求某处长时间滞留,A重传连接请求,建立释放连接,很晚终于到B,B以为A又来连接并确认,A认为自己并未要求连接,不理睬B的确认(发拒绝RST)
SYN,FIN消耗一个序号
在这里插入图片描述

双方都可释放,第二第三报文重复ack(u+1), 第四报文seqno u+1
进过2MSL(最长报文段寿命),MSL多为2分钟。
1 保证第四个ack能到对端,ack丢了B重传第三报文,此时A可再传第四ack(重启2MSL计时器)
2 经过这段时间,保证连接内产生的所有报文从网络中消失
保活(keepalive)计时器:对端(多为客户端)挂了,不发数据来,我这连接还留着吗?
收到一次数据,重设计时器,计时器超时主动发探测报文。

在这里插入图片描述tcp有限状态机

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值