TCP协议中有几个关键的点:
- TCP通信是需要建立连接的;
- 数据的发送是全双工的;
- TCP通信是可靠的;
那究竟是如何实现的呢?
TCP建立连接
1、什么和什么连接
TCP把连接作为最基本的抽象。TCP的许多特性都与TCP是面向连接的这个基本特性有关。
每一条TCP连接有两个端点。那么这两个端点具体是什么呢?不是主机,不是主机的IP地址,不是应用进程,也不是运输层的协议端口。
TCP连接的端点叫做套接字或端口。
端口号拼接到IP地址即构成了套接字。
套接字 socket=(IP地址:端口号)(这就不难解释为什么我们代码传的是IP地址和端口号)
2、连接为什么可靠?
TCP发送的报文段是交给IP层传送的。但IP层只能提供尽最大努力服务;
所以TCP可靠主要是靠一些可靠的传输协议:
停止等待协议
停止等待就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再去发送下一个分组。
- 无差错情况
- 出现差错
B收到错误的报文直接丢弃什么都不做;
A在一定时间段内没有收到确认报文,所以重传M1
实现的点:
-
必须暂时保留已发送的分组的副本
-
必须进行编号
-
设置超时计时器 且时间设置应该比在分组传输的平均往返时间更长一些
-
确认丢失和确认迟到
其实也很容易理解;
B收到了M1,但是发送确认的途中丢失或者迟到了,此时后来居上。
连续ARQ协议
滑动窗口协议比较复杂,是TCP协议的精髓所在。这里先讨论基本的APQ协议
提高信道利用率
- 发送方五个分组都可以连续发送出去,而不需要等待对方确认,当收到一个确认,滑动窗口向后移
- 接收方:累计确认,对按序到达的最后一个分组发出确认
优点:容易实现,确认丢失也不必重传;
缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息
深究可靠的原因?
-
源端口目的端口:
-
序号:TCP连接中传送的字节流中的每一个字节都按照顺序编号
-
确认号:期望收到对方下一个报文段的第一个数据字节的序号
-
数据偏移:指出TCP报文段的数据起始处离TCP报文段的起始处有多远
-
保留:占六位
-
紧急URG:当URG=1时,表明紧急指针字段有效。告诉系统此报文中有紧急数据,应尽快传送,而不是按照原来的顺序。(发送方TCP将紧急数据插入到本报文段数据的最前面,与首部的紧急指针做配合)
-
确认ACK:仅当ACK=1时,确认号字段有效。在连接建立后所有的报文段必须把ACK置1
-
推送PSH:当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即能够收到对方的响应。发送方TCP把PSH置1,并立即创建一个报文发送过去。接收方TCP收到PSH=1的报文段,就尽快交付接受应用进程,而不是等到整个缓存都填满才交付
-
复位RST:当RST=1时,表明TCP连接中出现严重差错,必须释放连接,然后重新建立运输连接。
-
同步SYN:在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意连接,则在响应的报文段中使SYN=1,ACK=1。(三次握手)
-
终止FIN:用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放连接**
-
窗口:窗口值作为接收方让发送方设置其发送窗口的依据
-
检验和:计算检验和时候,需要在TCP报文段的前面加上12字节的伪首部。
-
紧急指针:紧急指针仅在URG=1时才有意义指出本报文中紧急数据的字节数
-
选项:长度可变,最长40字节。
1、TCP可靠传输的具体实现
- (1)以字节为单位的滑动窗口
假定数据传输只在一个方向进行,A发送B接收
其实滑动窗口我觉得挺好理解的,对号入座,前面优先,前面没来的则必须等
上图是假设A——》B
切记TCP的通信是全双工通信。通信中每一方都在和接受报文段。因此,每一方都有自己的发送窗口和接受窗口,一定要弄清是哪一方的。
滑动窗口为什么能保证可靠呢?
我觉得就是主要是 按序交付上层的应用进程(对号入座)
,同时也可以减少传输开销,累计确认,不用一次一次的发送确认。
- (2)超时重传的时间选择
上文中讲到,TCP的发送方在规定的时间内没有收到确认就要重传已经发送的报文段。概念很简单,但重传时间的选择是TCP最复杂的问题之一。
如果时间过短:引起很多不必要的重传
如果时间过长:降低了传输效率
TCP采用一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间RTT。TCP保留了RTT的一个加权平均往返时间RTTs。
超时重传时间理论上略大于RTTs
而如何判定此确认报文段是对先发送的报文段的确认,还是对后来传输的报文段的确认?
根据往返时间RTT确认
(3)选择确认SACK
假如不是按顺序发送的,即TCP的接收方在接受对方发送过来的数据字节流的序号不连续——》那么接收方先收下这些数据,但要把这些信息准确的告诉发送方,使得发送方不用再重复发送这些已经收到的数据
使用前需添加SACK选项
2、TCP的流量控制
- (1)利用滑动窗口实现流量控制
所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接受。
发送方的发送窗口不能超过接收方给出的接受窗口的数值
- (2)TCP传输效率
如何控制TCP发送报文段的时机仍然是一个较为复杂的问题?
3、TCP拥塞控制
在计算机网络中的链路容量(即宽带),交换结点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。
其实和堵车的原理大致相同。
堵车怎么解决,盲目加宽路面,想必不然;归根结底是控制车辆,制定规则。
网络中的解决也大致相同,拥塞控制:防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制是一个全局性的过程。
例:TCP连接的端点迟迟不能接受对方的确认信息,很可能在某处发生了拥塞。但具体发生在何处呢?
流量控制:指点对点通信量的控制,是个端到端的问题
方法:抑制发送端发送数据的速率,以便接收端来得及接受
拥塞控制非常难设计,是一个动态的过程
TCP控制拥塞的方法
慢开始 拥塞避免 快重传 快恢复
- 慢开始和拥塞避免
慢开始:当主机开始发送数据时,由于并不清楚网络的负荷情况,所以如果立即把大量数据字节注入到网络,那么就有可能引起网络发送拥塞。所以方法是由小到大主键增大发送窗口即有效到大逐渐递增拥塞窗口数值
判断拥塞方法:超时确认
具体算法参考计算机网络书籍;
拥塞避免:拥塞窗口cwnd按线性规律缓慢增长(比慢加载算法的拥塞窗口增长速率缓慢的多)
- 快重传和快恢复
我觉得看下图就好了
3、具体过程
三次握手,下篇博客见~
7.31整理