TCP协议

一. 运输层概述
为什么需要运输层
四层协议中,数据已经能够从主机A传输到主机B,那么为什么还需要运输层呢?原因是网络中各个主机直接的通信实际上是主机上面的各个进程之间的通信,所以当一个主机拿到数据之后,需要将数据运输给该主机上面的某一个特定的进程,所以这个时候出现了运输层这个 概念。
运输层的中的 两个重要的概念是 复用分用。复用:各个进程进行 传输数据的时候,可以使用同一个协议;分用:数据在传输的时候,能够知道数据传输给那个特定的进程(这个 根据报头确定)。(收发室例子)
为什么需要端口号
在之前的学习基础上,我们知道我们可以通过一个IP地址唯一的确定网络中的一台主机,这个实现了复用,那么我们如何实现分用呢,即如何将数据传输给特定的进程呢,我们想类似于操作系统中的使用 一个 进程描述符,但是这种方法是不可行的 ,因为操作系统多种多样,而且不同的操作系统使用不同的进程描述符,无法统一起来,这个时候就出现了端口号,用端口号来标识唯一的进程。端口号16位,提供65535个进程描述,这是足够用的了。
我们说端口号唯一的标识一个进程,这些进程可以理解为应用层的,我们这里列举一些熟知的端口号,FTP:21,HTTP:80....( 这里的FTP和HTTP就可以理解为一个一个的应用程序
运输层主要由两种 协议,一种是用户数据报协议UDP,一种是传输控制协议TCP。
二. 传输控制协议TCP概述
1.TCP的主要特点呢
TCP是面向连接的运输层协议
每一条TCP都有两个端点(套接字)
TCP提供可靠交付的服务
TCP提供全双工的通信
面向字节流的
2. TCP连接
每个TCP连接有两个端点,这两个端点被称为套接字,套接字的形式是下面这个样子的
套接字socket = IP地址:端口号
类似于192.3.4.5:80,这个表示IP地址是192.3.4.5上面的HTTP服务

3. 可靠传输工作原理( 可靠性
等待停止协议
(1)无差错的情况
比如我们这里有一个TCP链接,分别是数据发送方A和数据接收方B,这个时候我们的A向B发送数据M1(假设连接已经建立起来了),然后等待B确认;B接受到A传递的数据之后,给A发送一个信号,表示B已经 接受A传输的 数据了,这个时候A再次向B发送数据。
(2)出现差错
如果我们的A向B发送 数据之后,等待B确认返回,但是这个时候B检测到数据中有错误信息,然后B不给A发送确认信息;或者是A发送 数据之后,这个数据并没有传输到B,这个时候B不知道,于是B什么都不做。上面的两种情况就是B不发送 任何返回信息。
可靠性是这样 设计的:A在等待B的确认信息之后,等了一段时间之后还没有收到B的确认信息,于是A重新发送数据,这个就是 超时重传。要实现超时重传,在发送一组数据之后,设置一个计时器,当这个 计时器超过了时间之后,就会重新发送 数据,如果发送方收到了来自接收方的确认信息,这个时候计时器就会取消掉了。
实现超时重传还需要注意一下的几点:
第一,为了重传,每次发送方发送完一个分组之后都需要保留一个副本,一遍下次重新发送 数据,这个副本知道发送方收到确认的信息之后可以删除掉。
第二,为了维护确认信息,需要为每一组数据进行一个编号。
第三,计时器的时候设置应当比数据传输的时间要长,但是又不能太长,如果太长效率就会低下,这是一个很复杂的过程,视具体情况而定。
(3)确认丢失和确认迟到
发送方在发送数据时候可能会出现错误,同样的道理,接收方也可能出现错误,比如接收方的信息已经接受了,这个时候接收方给发送方发送一个确认信息,但是这个确认信息在中途丢弃了,或者是发送确认信息的时候超过了计时器的时间了,这个时候发送方就会超时重传,重传的分组编号和刚刚的不变,在个时候接收方接收到同样的信息之后,直接丢弃该信息,然后继续发送确认信息。

向上述的 自动重传请求ARQ
4.效率
每次发送 一个分组然后等待确认信息之后再发送 下一个分组,这里有很多的时间就浪费在了数据传输和确认信息上面了,为了提供效率,发送 放可以每次发送多个分组。这里就是流水线传输了。
为了适应 上面的流水线传输数据,又出了两个协议,一个是 连续ARQ协议,一个是 滑动窗口协议
滑动窗口协议,发送方一般把多个分组放在一个连续的数组中,然后然后确定一个滑动 窗口的大小,比如是5,那么这个时候发送方一次发送五个分组,而不是发送一个等待一会发送一个等待一会,这个时候就提高了网络的利用率了,然后等待收到确认信息之后,滑动窗口向后滑动的一定的距离,然后继续发送 多个数据,这里滑动一定的距离是因为,接收方不是一个一个确认的,而是按照顺序一个确认多个,然后发送最后一个确认信息。

三. TCP报头信息

1. 16位源端口号和 16位目标端口号
2. 序号和确认序号
序号占据了32个位,一共可以表示的范围是[0,2^32-1]。TCP是面向字节流的,它为每一个字节编制了一个编号,当发送 放发送一组数据时候,序号里面的大小是这一组数据的首地址的值,比如这里的首地址的值是1,然后数据的大小是1024,那么下次发送方发送数据的时候,序号里面的数据应该是1025。当接收方发送 确认下信息的时候,比如接受的数据的里面的序号是1024,数据的长度是20,那么数据的编号是[1024,1047],那么这个时候接收方发送的数据中的确认序号应该是1048,。
3. 4位首部长度(数据偏移)
这个字段实际上表明了TCP的首部长度,因为首部中 有一个固定部分和一个可变部分组成。
4. 保留
占据6个位,为以后的使用
5.
紧急URG
当URG为1时,表明紧急指针字段有效,它告诉系统此报文中有紧急数据,应该优先处理,而不是按照原来的顺序传送数据。
这个时候紧急URG要与紧急指针配合着使用。
确认ACK
当ACK=1的时候有效,当ACK=0的时候无效。TCP中建立连接的两个套接字直接的ACK必须都是1,否则就是没有确认的。
推送PSH
有的时候需要发送的一个报文立即得到响应,这个时候发送方可以把PSH设置为1.
复位RST
当RST=1的时候说明TCP连接中有重大的错误,必须释放之后然后重新连接。RST=1,还可以用来拒绝一个链接。
同步SYN( 发送连接 建立请求 )
当SYN=1,并且ACK=0的时候,说明这是一条请求连接的报文。
终止FIN
用来释放一个连接,当FIN=1的时候,报文发送完毕,并且要求释放连接。
6.16位窗口大小
2个字节,窗口值是[0,2^16-1],窗口值指的是,发送报文段的一方接收数据能力大小。窗口值告诉对方:从本次报文段首部中的确认字号开始,接收方目前允许接收的最大数据量。
7. 检验和
2个字节,检验和检验的是首部和数据这两个部分。
8. 紧急指针
2个字节,紧急指针仅在URG=1的时候有效,紧急指针指出了紧急数据的末尾在报文中的位置。
9. 选项
选项是可变的,当没有选项字段的时候,首部的大小是20字节。选项的最大长度是40字节。

上面的字段中没有MMS,这里补充一个概念是MMS,不是TCP首部中的字段,MMS的含义是,最大报文数,就是,TCP报文中,数据字段的最大长度,如果长度过大,每次需要划分分组,如果长度过小,数据的大小可能 还没有TCP首部的大小大,这也是造成效率底下的一个原因。


四。 TCP可靠传输的实现
1. 滑动窗口大小
如果A接受到了B发来的确认信号,此时B的窗口是20,确认信号是31,即表示A发送给B的前面的30个字节都确认收到了,B期望收到A发送字节号是31的数据,这个时候A根据确认号和窗口选择发送了31到50这些是数据。
可以这样理解就是A的发送窗口是根据B的接受窗口的大小来确认的,但是并不是发送 窗口的大小一定是和接受窗口的大小的来确定的,发送方 还需要考虑网络中拥塞的现象的存在。
对于不按序到达的数据,如果接收方一律把它丢掉,这个时候虽然处理起来比较简单,但是这造成了网络了压力,所以这个时候应该是把不按序到达的窗口保存在一个缓冲区总,然后等到全部到达之后在统一的交付给上层的应用层
2. 超时重传时间的选择
网络中是非常 复杂的,这个时候超时重传的时间很难确定,如果时间太多,经常性的重传,这造成网络的压力太大,如果时间太长,造成效率太低。
TCP超时重传采用了一种自适应的算法。发送方记录了一个发送的时间和一个数据确认的时间,这个时间就是RTT,报文段的往返时间。然后每次根据这个时间,使用一个公式来确认超时重传的时间。每次超时重传的时间根据上一次的RTT的时间来确定,所以每次的时间都是不确定的。但是变化不大。
3. 选择确认SACK
还有一个问题就是,如果有些情况是某些数据已经到达,但是这些数据前面的数据由于某些原因没有到达,这个时候也是需要超时重传的,但是可以值传递前面没有到达的数据,而这些已经传递的数据就不在传递了呢,答案是可以的,这里用到的方法就是选择确认
接收方先把这些数据存放在一个缓冲区当中去,然后告诉发送方一些信息,这些信息就是已经收到了哪些数据。接收方是通过一个一个指针维护这些数据信息的,但是TCP首部中没有标记这些信心,于是用到了那个选项字段,这里加上了一个“允许SACK字段”。
五. TCP流量控制
1. 利用滑动窗口进行流量控制
前面已经讲述过这个概念了,这里还有一种情况就是,如果接收方的话都能窗口是0,这个时候发送方就不在发送数据,然后因为其他的原因接收方滑动 窗口变大了,这个时候接收方给发送方告诉他的滑动窗口,但是因为某些原因数据没有到达,为了解决这种情况,又有了一个持续计时器。
2. 考虑传输效率
六. 拥塞控制
拥塞控制,就是防止过多的数据注入到网络中,这样可以使网络中的路由器和链路不至于过载。
1. 几种拥塞控制的方法
慢开始、拥塞避免、快重传、快恢复
发送方有一个拥塞窗口,这个窗口的大小根据网络的拥塞程度而动态的变化,发送方使自己的窗口的大小在小于接收方窗口大小的前提下,尽量的等于拥塞窗口。
下面就是如何知道发送窗口的大小,首先从 慢开始算法说起,当发送方把数据发送到网络中去了之后,就有可能导致网络的拥塞,因此这个时候可以设置自己的发送窗口小一些,然后试探一下是不是造成拥塞了,如果没有再稍微增大一点,这样一点一点试探就好了,逐渐增大拥塞窗口的值。这里设置的cwnd=1,以后每次变成原来的2倍。这里需要设置一个慢开始门限ssthresh,如果cwnd<ssthresh,使用的是慢开始算法,如果cwnd=ssthresh的时候可以使用慢开始算法,也可以使用 拥塞避免算法。,
避免拥塞算法其实也很简单,它不是每次增大到 原来的二倍,而是每次增加1.但是又不能无休止的增加下去,每次当我们出现拥塞的时候就把ssthresh减少到原来的一半,并且把cwnd的大小调整到1继续开始后慢开始算法。
接下来是 快重传算法,当接收方的接受的数据失序了之后应该立即给发送方发送信息告诉他信息失序了,而不是等到接收方想发送方发送数据时候捎带着发送失序信息。而当发送方接受到三个接收方发送的失序信息之后就立即重传信息,而不是等待计时器时间到了之后才开始重传。
然后是快恢复算法,当发送方接受到了三个重传信息之后,使用乘法减半算法,就是刚刚的把ssthresh的值减少到原来的一半,但是现在并不把cwnd的值设置为1,而是设置为ssthresh,然他执行拥塞避免算法。
七. 随机早期检测RED
我们的路由器是以队列的方式把数据存储起来一一处理的,当某些时候,处理某个报文的时间过长的时候,导致队列中的数据满了的时候,后进来的数据就会被丢弃掉了,这个时候发送方就会出现超时重传,进入到慢开始状态,这个时候可能同时有很多个链接和路由器连接起来的,这个时候都会出现慢开始状态,但是当网络恢复了之后,数据又会同时增长起来,这个被称作是全局同步,为了避免这个问题,就出现了随机早期检测RED。
这个时候路由器维护两个队列长度,一个是最小门限THmin,一个是最大门限THmax,(1)当队列的长度小于THmin的时候就把数据放置在队列中进行 等待,(2)当数据的长度超过THmax的时候,就把新到达的分组丢弃,(3)当再THmin和THmax之间的时候,就按照某一个概率将部分的分组丢弃。随机早起检测中的随机就体现在(3)中。
通过上面的方式就避免了全局的拥塞。
八. TCP的运输连接管理(三次握手)
TCP协议是面向连接的,运输层的连接分为三个阶段:连接建立,数据传送,和连接释放
TCP连接建立的过程是客户服务器模式,主动发起请求的一方是客户,被动的等待连接的是服务器。
我们假定A主机是客户机,即主动发送连接请求的,而B主机是服务器,是被动的建立连接的,此时B主机先建立一个传输控制块TCB,然后进入LISTEN状态,等待客户发送连接请求,如果有,即作出反应。
此时A也创建传输控制块TCB,然后向B发送请求,此时首部中的同步位SYN=1,同时携带一个初始序号seq=x,这个序号就是报头中的32位序号中的字段( 一次握手完成)。
B接受A的请求之后,如果同意建立连接,则向A发送确认信息,在确认信息的报头中应该把SYN和ACK都设置为1,同时确认序号是ack=x+1,同时也选择了自己的序号是y。此时这个报文时不携带任何 数据的( 二次握手完成)。
A收到B的确认信息后,还要向B发送确认。确认报头ACK设置为1,确认号是y+1,同时自己的序号是x+1。此时A可以选择发送数据也可以选择不发送数据,这个时候如果发送数据,则序号消耗,如果不发送数据则序号不消耗。( 三次握手完成)这个时候连接就已经建立起来了。
为什么又A还需要发送一次确认信息呢,主要是防止已经失效的连接请求报文突然又向B发送数据,这个 时候B已经断开连接了,它是不会接受这个数据的。这种情况可能是这个样子,就是A给B发送数据请求,但是因为网络阻塞等原因,A的第一次发送的请求不能及时到达,这个时候A又一次放你请求,这个时候请求可能到达了,然后建立连接,某些时候,这个时候链接已经断开了,但是这个时候A第一次发送的请求才刚刚到达,这个时候如果没有三个握手,B直接给A建立连接了,岂不是白白的浪费了。

九. TCP的释放连接
此时A的服务已经 完成了,A向B发送请求断开连接,这个时候A发送的报头中的FIN位置为1,表示请求断开连接,同时seq=u,这个u等于前面已经发送的数据信号加上1,TCP规定,FIN即使不携带任何数据,它也是消耗一个序号的( 第一次挥手)。
然后B接受到A发送断开请求的数据的时候,然后给A发送报文,确认号ack=u+1,并且这个报文自己的报文序号是v,这个 v等于前面的已经发送的报文的序号+1。此时B进入到半关闭状态,即是此时A到B的连接已经关闭了,但是B到A的连接还没有关闭,即A不能 向B发送数据,但是B可以先向A发送数据。B此时做的事情是通知上层的应用层A已经和自己断开连接,等待下一步的处理( 第二次挥手)。
若此时B已经没有数据要向A发送,这个时候B发送 连接释放的报文,设置自己的FIN为1。假设B的序号是w,因为在A断开连接 的时候B没有断开连接,这个过程当中B还肯能向A发送了一些数据,所以序号改变了。B还是应该重复自己的确认信号。ack=u+1( 第三次挥手).
A收到B的断开信息后,必须对此作出确认,这个时候ACK设置为1,ack设置为w+1,然后自己的信号是seq=u+1。( 第四次挥手
还应该考虑的一种情况就是,A可能因为某些原因宕机了,这个时候B应该设置一个保活计时器,就是当A长时间不发送数据的时候,B会主动和A断开连接。

可靠性总结
1. TCP是基于请求确认机制的
2. TCP保证数据的按序到达
3. 丢包重传
4. 面向连接的,确认可靠性
5. TCP进行流量控制
6. TCP提供了各种定时器
7. TCP实现了避免网络拥塞的算法





































  • 11
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值