什么是计算机网络?
什么是网络协议?
计算机网络的结构
数据交换之电路交换
数据交换之报文交换和分组交换
分组交换 vs 电路交换
计算机网络性能(1)——速率、带宽、延迟
计算机网络性能(2)——时延带宽积、丢包率、吞吐量/率
计算机网络体系结构概念
OSI参考模型基本概念
OSI参考模型中非端-端层(物理层、数据链路层、网络层)功能介绍
OSI参考模型中端-端层(传输层、会话层、表示层、应用层)功能介绍
TCP/IP参考模型基本概念,包括五层参考模型
网络应用的体系结构
网络应用进程通信
网络应用对传输服务的需求
Web应用之HTTP协议(涉及HTTP连接类型和HTTP消息格式)
Cookie技术
Web缓存/代理服务器技术
传输层服务概述、传输层 vs. 网络层
传输层——多路复用和多路分用
传输层——UDP简介
传输层——可靠数据传输原理之Rdt协议
传输层——可靠数据传输之流水线机制与滑动窗口协议
传输层——TCP特点与段结构
传输层——TCP的可靠数据传输
我们知道,TCP是一个面向连接的传输层协议,所以在进行实际的数据传输之前要先进行连接的建立,等到数据都传输完成后还要进行连接的拆除。那这个是怎么实现的?下面一起来看看。
TCP sender 和receiver在传输数 据前需要建立连接。
在建立连接的过程中,会初始化TCP变量,或者说选择自己的序列号,也会分配相应的资源,比如分配缓存、交换流量控制信息等等。
一般来说,连接的发起者往往是Client客户端,Server服务器这一端则是等待客户连接请求,并且在有可用资源的时候会接收这个请求并建立连接。
在TCP连接建立的过程中,采用了三次握手的机制。这是非常重要的。三次握手是指TCP连接的建立过程分三个阶段(在这个过程中会涉及三个包的传输),基本原理如下:
Q:为什么要有三次握手?而且三次握手机制不仅仅在计算机网络中存在,在很多现实当中也是广泛使用的。
以下解释引用自https://cloud.tencent.com/developer/article/1874945
A:原因:避免重复连接
其实在RFC 793 Transmission Control Protocol里就有指出为什么要三次握手的原因
The principle reason for the three-way handshake is to prevent old duplicate connection initiations from causing confusion.
翻译为中文大致意思是主要原因是为了防止旧的重复连接引起连接混乱问题
比如在网络环境比较复杂的情况,客户端可能会连续发送多次请求。如果只设计成两次握手的情况,服务端只能一直接收请求,然后返回请求信息,也不知道客户端是否请求成功。这些过期请求的话就会造成网络连接的混乱。
所以设计成三次握手的情况,客户端在接收到服务端SEQ+1
的返回消息之后,就会知道这个连接是历史连接,所以会发送报文给服务端,告诉服务端。
所以TCP设计成三次握手的目的就是为了避免重复连接。
那么可以设计成四次握手?五次握手?不可以?答案是也是可以的,不过为了节省资源,三次握手就可以符合实际情况,所以就没必要设计成四次握手、五次握手等等情况。
下面这幅图展示了三次握手的简单过程:
ACK number是上一个序列号+1,这是确认前面的报文段收到了,同时告知对方下一个期待的报文段的起始序列号。
如果第三个步骤中客户端的ACK没有成功发给服务器,那服务器再第二个步骤所创建的资源会保留一段时间,一直到确认这个连接不会再建立了,才会释放资源。这种TCP连接管理为经典的 DOS攻击 即 SYN洪泛攻击 提供了环境。在这种攻击中,攻击者发送大量的SYN 请求连接报文段, 而不完成第三次握手 ,也就是不回复ACK确认报文段。 如果服务器不断地响应请求, 为这些半开连接分配资源 ( 但从未使用 ), 就会导致服务器的连接资源被耗尽。
关于TCP连接的建立就介绍到这里,下面介绍如何关闭或者说拆除连接。
TCP连接的拆除是客户机和服务器都可以发起的。但多数情况下是客户机发起关闭的请求。
客户机的socket执行一个close函数,意味着客户机声明想要关闭连接。接下来会有四个步骤(在这个过程中会涉及四个包的传输):
TCP协议在不同的状态之间来回切换。下面展示了典型的TCP客户端和服务器的生命周期,也就是状态的变化过程。
客户端:初始的时候,TCP客户端处于关闭状态。当上层也就是应用层有一个应用需要TCP连接的时候,TCP客户端会尝试建立连接,向服务器发送SYN报文段。这时会进入SYN已发送的状态。然后等待SYN & ACK报文段,收到之后会回复ACK,这时会进入已经建立连接的状态。这个时候就可以为上层应用可靠的传输数据了。当上层应用使用完连接后并想要关闭连接,这时TCP客户端会发送FIN报文段并进入FIN_WAIT_1状态。如果收到ACK的话,进入FIN_WAIT_2状态,等待服务器端发来的FIN报文段。收到后发送一个ACK,这时再进入等待状态,一般来说会等待30s,这个过程如果又收到FIN ,会重新发送ACK,否则30s结束,进入关闭状态。
服务器: