挑战408——一周网络——运输层(3)
TCP协议
TCP协议的主要特点
对比UDP协议,TCP协议就要复杂很多了。对比UDP协议,TCP协议有以下几点不同:
- TCP是面向连接的传输层协议。也就是说,使用TCP协议的通信双方事先就要建立连接,在整个连接过程当中控制个管理连接,并在通信之后释放整个连接。
- TCP连接只能是一对一的。也就是每一条TCP连接只能是两个端点。
- TCP提供的是可靠交付服务。也就是通过TCP连接传输的数据,无差错,不丢失,不重复,并按序到达。
- TCP提供全双工通信。即允许通信双方的进程,在任何时候都可以发送数据。这就要求通信双方要有自己的发送和接收缓冲区,用来临时存放双方通信的数据。
- TCP是面向字节流的。这部分后面再说
TCP的连接
每一条TCP连接有两个端点,这个端点叫套接字,其表示方法是IP地址 + 端口号。
这样,同一个IP可以有多个不同的TCP连接(IP相同,端口号不一致),同一个端口号也可以出现在多个TCP连接当中。
TCP首部
TCP的首部前20字节是固定的,后面有4n个字节是可选的。也就是说,TCP的首部最短是20字节。
- 源端口和目的端口:略。哥占2个字节(一个字节8位)。
- 序号:在TCP传送的每一个字节流中的字节都按顺序编号,占4个字节,范围为[0 - (2^32)-1]。上一篇中的连续ARQ协议中,窗口数据的序号就是这样编的。
- 确认号:即期望收到对方下一个报文段的第一个数据字节序号。即若发送方收到确认号 =N的确认号,则表明N-1之前的数据都已经正常被对方接收,接下来发送N-1之后的报文。一般的,当***被重复使用的时候,可以认为旧的报文段早已经通过网络到达终点了。
- 数据偏移:即TCP报文的数据起始处距离TCP报文起始处的距离(也就是TCP首部的长度)。数据偏移的长度是以4字节为单位的,因此数据偏移的最大能表示的十进制数是15,也就是说TCP首部最大长度为60字节。
- 紧急URG:当URG为1的时候,表示此报文有紧急数据,需要优先传送。于是发送方就把紧急数据插入到本报文段数据的最前面。需要与紧急指针配合使用。
- 确认ACK:当且仅当ACK =1的时候确认有效,ACK = 0时无效。TCP规定,连接建立后,TCP的所有ack确认报文都应该置为1.
- PUSH位:略
- 复位RST:当RST = 1的时候,表示这TCP连接过程出现错误,需要重置连接。
- 同步SYN:在建立连接时用来同步序号。当SYN = 1,且ACK = 0的时候,表明这是一个请求连接的报文。若对方同意连接,则回复响应保卫SYN=1,ACK = 1. 总之,SYN=1,表明这是一个请求连接或者接受连接的报文。
- 终止FIN:当FIN = 1的时候,表明要求释放连接。
- 窗口:表明现在允许对方发送的数据量,窗口值在时刻动态变化。
其他字段略过。
TCP的连接管理
TCP是面向连接的协议,而TCP运输连接的建立都需要建立和释放连接。对于TCP连接而言,运输过程需要下面三个过程:建立连接,数据传送,释放连接。TCP连接采用C/S模式,发起连接建立的客户端称为客户,而被动等待连接的称为服务器。
三次握手
TCP建立连接的过程称为握手。建立连接的过程需要客户端与服务端之间交换三次TCP报文段(这就是所谓的三次握手)。
初始状态,双方都处于关闭状态。现在模拟A向B发送TCP连接请求的过程:
- A主动打开连接,B被动打开连接。(此时B处于Listen,监听状态)
- A打算与B 建立TCP连接,于是向B发出请求连接报文段。根据刚刚学习的首部,这个时候SYN = 1,Seq = x。此报文不携带任何数据,但消耗一个序号。同时为TCP连接分配缓存空间和变量
- B收到后,若同意连接,于是向A 发送连接确认。此时SYN = 1 ,ACK = 1,seq=y,ack = x + 1. 注意,这里的ACK是TCP首部字段的确认ACK,而ack是确认号,也就是下次要发送的序号。此报文不携带任何数据,但消耗一个序号。同时为TCP连接分配缓存空间和变量
- A收到B的确认后,还要给B 发送对B确认的确认。此时ACK = 1,ack = y+1.seq = Y+1.此时连接建立。可以正常传输数据。不带数据可以不消耗一个序号
以上步骤除去1,就是TCP三次握手的过程。
考虑这样一种情况,如果A发送给B的请求连接的报文超过一段时间都还没有收到B的确认(即走到步骤2这一步走不下去了),根据我们之前的停止等待协议,我们就认为这个报文丢失了,这里应该再次给B发送连接请求。这是AB建立正常的TCP连接,然后传输数据,释放连接。倘若此时,A的请求连接不是丢失,而是迟到了,当A的请求到达B的时候,AB早已完成通信,此时,B会认为A再次请求连接,并且B给A发送了确认。但是A此时并没有请求通信,如果此时A不在向B发送确认的确认(也就是不要第4步),这样服务器只能苦苦等待A的请求,白白浪费服务器资源。
四次握手
TCP连接的释放需要进行4次的握手。这里有个概念,TCP是全双工通信,可以看成一条TCP连接上有两条数据通路。
通信结束后通信双方都可以结束通信。这里模拟一下A主动结束通信的过程。
- 通信结束,A主动向B发送连接释放报文。并停止发送信息,主动关闭TCP连接(由于全双工通信,对方仍可以给A发送信息)。此时 FIN = 1,seq = u,其中u的值是等于之前发过的数据最后一个字节的序号 + 1.TCP规定,FIN报文要消耗掉一个序号。
- 服务器收到A发来的关闭连接的报文,于是向A发出确认。此时确认号ack = u+1,报文段自己的序号seq = v(这个值等于服务器之前传送过的最后一个数值序号+1)。然后B进入 close -Wait状态(半关闭状态)。此时客户端到服务器这个方向的连接关闭了。(但是服务器到客户端的仍未关闭,服务器还是可以向客户端发送数据)。
- 若此时B已经没有要向A发送的数据了,此时,B发出释放连接报文。置FIN = 1.(此步骤跟1相似,不赘述)。
- 客户端收到B发来的释放连接时,还必须发出确认。具体参数的值见图。此时服务器进入TIME-WAIT状态。这个状态表明连接还没完全释放,必须等候一段时间,这个时间为时间等待计时器2MSL。A才进入关闭连接状态。
关于序号的分析,个人感觉还是自己分析一遍。填写一遍才会印象深刻。