对码当歌,猿生几何?

TCP/UDP的连接与关闭详解

传输层:

总体作用:在广域网中建立数据传输通道,进行数据传输,负责端到端的通信

那么是什么是端到端呢?
A: 两个方面
- 物理实际意义上,意味着网络通信双方不再同一链路上,不是点对点连接的(通信双方直接通过电缆进行通信,直接相连,中间没有其他设备)
- 虚拟上,以用户的角度,两端是直接进行的,不考虑核心网络结构和各种子网间的差异。

服务类型:TCP和UDP
-  TCP:面向连接,提供服务前建立专门的传输连接,并且这条连接可管理,在需要或通信结束时进行拆除。面向连接的传输服务是可靠的传输服务,提供拥塞控制、差错控制和流量控制。
- UDP:无连接,直接发送,不管是否能达到,尽力而为

TCP:其建立在不可靠的分组传输服务上,可能出现丢失、乱序、延迟、重复等等问题。

基本特性

  • 面向连接

  • 只能支持单播,socket端口到端口

  • 可靠的交付服务,无差错、不丢失、不重复且按时序到达(主要利用ACK、超时重传、乱序重排和整理)

  • 数据段来传输,又是在应用层传送的数据基础上进行封装的,因此TCP
    数据段的大小是取决于不同的应用进程的,其受MSS和应用层传送的报文大小共同决定。

  • 如果应用进程传送到TCP缓存中的数据太长,需要分段,反之,如果传到TCP缓存中的数据太小,则TCP会等待缓存中有足够多的数据后再组成一个数据段一起发送。

  • 全双工,TCP连接的两端都设有缓存

  • 可以同时建立多个并发的连接

  • 基于字节流,没有边界限制,相当于一个管道,从一端放入什么内容,另一端可以照样取出什么内容,描述了一个不出现丢失、重复和乱序的数据传输过程。

  • 每次发送的字节是不固定的,依赖于对方给出的窗口大小和当前网络的拥塞程度来决定

数据段格式
通过数据段的交互来建立连接、传输数据、发送确认、差错控制、流量控制和关闭连接等。数据段头,TCP实现端到端可靠传输而加上的TCP控制信息,数据接受自上层应用层的用户数据。

4.png

  • 端口:

  • 序号:TCP数据段中的数据部分的第一个字节的编号,TCP按照顺序进行编号,这个必须建立在双方建立连接的前提下进行。

  • 确认号:期望接受到对方下个数据段中的”数据”部分的第一个字节序号

  • 数据偏移:确定TCP数据段头部分的长度,去除不确定的可选项字节,找出数据的位置 URG:紧急指针,紧急数据优先安排

  • ACK:确认控制位,只是一个flag,表示”确认号”字段是否有效 PSH:推送控制位,表示是否需要立即把收到的数据段提交给应用进程

  • RST:重置位,用于重置、释放一个已经混乱的传输连接,然后重建新的传输连接,为1释放

  • SYN:同步控制位,用来传输连接建立时同步传输连接序号,占1位,SYN=1,ACK=0,代表连接请求或连接确认报文

  • FIN:最后控制位,释放一个连接,置1时数据已全部传输完成,没有数据要传输,释放当前连接,接受端还可以接受尚未接受完的数据。

  • 窗口大小:存储传入数据段的窗口大小,也就是发送方当前可以发送的最大字节数,进行流量控制,接收方通知发送发下一次可以连续传输的字节数。

  • MSS: TCP最大端长度,最多在数据字段中放置的数据字节数量,选择MSS值时需要考虑到协议开销(太小的话,有用数据小,传的都是报头)、IP分片(TCP是基于IP层的分组传输的,如果MSS值太大,造成IP层,增加网路层的开销和传输出错的概率),还有发送和接收缓冲区的限制。

  • 检验和:对数据段头、数据和伪头部这三部分进行检验

  • 紧急指针:指出本数据段中为紧急数据的字节数

socket
区分不同应用进程间的网络通信和连接,实现数据传输的并发服务,TCP/IP通信中,应用程序把数据传送给socket,由socket通过传输层向下提交给网路驱动程序并向网络上发送出去。计算机从网络上收到与该socket绑定IP地址和端号相关的数据后,由网络驱动程序通过传输层向上提交给应用层的socket,最后应用程序从socket中提取所要接受的数据。

1.pngTCP连接的状态转移
2.png

3.png

连接状态详解

连接过程,由客户发起,三次握手保证了双向的连接
1. 开始,服务器顺序调用SOCKET、BIND、LISTEN和ACCEPT从closed状态进入被动打开状态,等待客户的连接请求
2. 客户从CLOSED状态开始调用SOCKET创建新的套接字,调用connect,本地TCP实体创建一个连接记录,对服务器进行请求,开始进行握手,发送SYN数据段(SYN置1),客户为SYN_SEND状态(已发送连接请求,等待服务器确认)
3. 服务器收到客户端的SYN后,回送ACK数据段(ACK置1),同时发送SYN数据段(SYN字段置1,接受同步请求),确认号为应答报文加1,被动打开端口,此时进入SYN_RECV(接受到请求,尚未确认),二次握手。
4. 客户端收到服务器发来的SYN和ACK后,给服务器发送一个ACK数据段,进入ESTABLISHED状态,三次握手,建立单项连接。
5. 服务器收到ACK后,同时进入ESTABLISHED状态,完成三次握手,完成双向连接的建立。

以上,建立完三次握手之后,双方建立起连接,就可以开始进行数据传输了。

4.png

特殊情况:同时连接,此时会发生连接碰撞,最终只有一个连接建立起来

5.png

关闭过程,由客户发起
此时需要四次释放,只是由于TCP的半关闭特性造成的,因为一个TCP连接时全双工的,每个方向必须单独进行关闭。

1.png

  1. 开始处于ESTABLISHED状态,如果客户认为数据全部发送完了,要结束会话时,客户端调用CLOSE,发送一个FIN数据段,FIN位置1,等待服务器确认响应,进入FIN WAIT_1状态,这个状态其实就是一个等待服务器回应的状态
    (在这个状态下,有三种方式响应方式,如上图所示,不常见的响应有:客户端收到没收到ACK却收到了FIN,然后客户端发送ACK,处于CLOSING状态,直到收到第一个确认ACK,进入TIMED_WAIT;另外一种可能是一同收到了FIN和ACK,那么直接进入TIMED_WAIT)

  2. 服务器收到FIN后,了解到客户没有新的数据来了,需要给客户端返回ack,置ACK为1,进入CLOSE_WAIT状态,此为自己服务器自己等待关闭。同时,服务器的TCP通知对应的应用层进程释放从客户端到服务器的连接,进入半关闭状态,此时服务器可向客户发送,客户也可接,但是客户不能发。

  3. 客户端收到服务器的ACK确认后,进入FIN WAIT_2状态,此时一个方向上的连接断开,但仍可以接受服务器端发来的数据段,进一步等待服务器发送连接释放的数据段。

  4. 服务器收到客户端发来的FIN数据段后,知道客户端有数据发送,等待数据接受完后,服务器也开始发送自己的数据,当数据发送完后,也应调用CLOSE原语,请求关闭另一个方向上的连接,然后发送FIN数据段,FIN置1,ACK置1,进入LAST_ACK状态,等待客户端的确认。

  5. 客户端收到服务器的FIN数据段后,向服务器发送一个ACK确认数据段,进入TIMED_WAIT状态,双方断开连接,再等待2MSL,保证连接上的数据全部结束,防止出现确认丢失,然后返回初始状态,双方关闭,CLOSED。

  6. 服务器收到最后一个ACK后,释放连接,删除记录,返回CLOSED。

问题:
Q: 那么为什么是2MSL呢?
A: TCP端口不能被同时打开多次,当一个TCP连接处于timed_wait状态时,我们将无法立即使用占用的端口建立新连接。那么如果不存在这个状态,应用程序会立即建立一个和刚才一样的连接,可以称之为原来连接的化身,这时可能接收到原来连接上的数据,但是这是不应该出现的问题。那么TCP报文段最大的生存时间是MSL,那么坚持2MSL就可以保证两个传输方向上尚未接收到的和迟到的TCP报文段都消失,就能保证新的连接安全的建立,不受到原连接上应用程序的数据。

特殊情况:同时关闭

2.png

特殊情况下,TCP连接的一端会向另一端发送携带RST标志的报文段,通知对方关闭连接或重新建立连接。
访问不存在的端口,或者是端口正处于TIME_WAIT状态的连接所占用时,客户端程序也将受到RST
异常中止,利用socket的SO_LINGER发送RST,中止连接

可靠传输
  字节编号:以字节为单位对数据进行一一编号,确保每个字节的数据都可以有序传送和接受
 数据段确认:确认接受到的数据段
 数据段:是TCP从上层接受到的数据进行分割得到的数据块,通常包括千个以上字节,而且必须是整数倍字节数,所以TCP是字节流。
 窗口大小:本段告诉对端可以接受的数据量,窗口大小必须小于MTU,不然到了链路层还是要进行数据分割。

特性:
1. 利用滑动窗口,可以使得TCP不需要等待接受对方发送的确认数据段就可以一次性连续发送多个数据段,可以提高传输效率。但是一次性发送的数据量受到对方返回的”窗口大小”和当前可用”发送窗口”大小双重限制的。
2. 仅对连续的数据段进行确认,最高接受到的数据字节序号+1。
3. 不连续的数据先缓存,等待接受到中断序号的数据段后进行重组再一起提交,
4. 超时重传时间RTO一般大于RTT
5. SACK,选择性确认(使TCP只重新发送丢失的包,不用发送后续所有的
包,而且提供相应机制使接收方能告诉发送方哪些数据丢失,哪些数据重发了,哪些数据已经提前收到等)

UDP:视屏、会话和语音电话,丢失一部分数据影响不大,不在乎数据的正确性。简洁、快速、高效,但不能提供必要的差错控制报文,同时在拥塞控制严重时缺乏必要的控制和调节机制。

  • 无连接

  • 不可靠,尽力而为

  • 以报文为边界,直接对应用层提交的报文进行封装、传输,但不拆分,也不合并,保留原有报文的边界,因此可以说成是报文流,到网络层后仍然可以根据网络的MTU值进行分割。

  • 无流量控制和拥塞控制,强调连续性,不强调完整性。

  • 支持各种通讯方式,组播、广播和点播。

  • 系统对性能要求高于对数据完整性的要求,丢失个别数据报影响不大的应用,如果用可靠性的TCP,那么就可能因为重传个人丢失的数据包而增大传输延迟

  • 需要”简短快捷”的数据交换,客户端发送简短的请求,服务器端回复简短的应答报文,可以简单设置”定时器”来处理丢失分离

  • 需要多播或广播

  • 与TCP相比,UDP不提供流量控制、数据应答和状态维护,最大的优势就是快,无连接,不保证数据的正确性,也不保证数据顺序,是一种无序的存在。

  • socket(); 设置端口和地址;sendto()向服务器发送数据;recvfrom()接受服务器数据;close()关闭套接字

阅读更多