计算机网络基础知识
开一个新的篇章,同时进行学习,只学习一种知识点太枯燥了,有点难啃。并且看到有的招聘网站上需要tcp/ip协议的科技树,所以学习一下。
参考书为《图解TCP_IP》
网络通信
网络通信本质上是一种进程间通信,是位于网络中不同主机上的进程之间的通信,属于 IPC 的一种,通常称为 socket IPC
网络通信是为了解决在网络环境中,不同主机上的应用程序之间的通信问题。
大概可以分为三个层次,如下所示:
(1)、硬件层:网卡设备,收发网络数据
(2)、驱动层:网卡驱动(Linux 内核网卡驱动代码)
(3)、应用层:上层应用程序(调用 socket 接口或更高级别接口实现网络相关应用程序)
在硬件上,两台主机都提供了网卡设备,也就满足了进行网络通信最基本的要求,网卡设备是实现网络数据收发的硬件基础。并且通信的两台主机之间需要建立网络连接,这样两台主机之间才可以进行数据传输。网络数据的传输媒介有很多种,大体上分为有线传输(譬如双绞线网线、光纤等)和无线传输(譬如 WIFI、蓝牙、 ZigBee、 4G/5G/GPRS 等), PC 机通常使用有线网络,而手机等移动设备通常使用无线网络。
在内核层,提供了网卡驱动程序,可以驱动底层网卡硬件设备,同时向应用层提供 socket 接口。
在应用层,应用程序基于内核提供的 socket 接口进行应用编程,实现自己的网络应用程序。需要注意的是, socket 接口是内核向应用层提供的一套网络编程接口,所以我们学习网络编程其实就是学习 socket 编程,如何基于 socket 接口编写应用程序。
除了 socket 接口之外,在应用层通常还会使用一些更为高级的编程接口,譬如 http、网络控件等,那么这些接口实际上是对 socket 接口的一种更高级别的封装。
计算机网络
计算机网络根据规模分为 了WAN(广域网)和LAN(局域网)。
TCP/IP协议是IP、TCP、HTTP等协议的集合。
在计算机通信中,事先达成一个详细的约定,并且遵守这一约定进行处理尤为重要,这种约定就是“协议”。
分组交换是将大数据分割为一个个叫做包(Packet)的较小单位进行传输的方法。计算机通信会在每一个分组附加上源主机地址和目标主机地址给通信线路。**这些发送端地址、接收端地址以及分组序号写入的部分称为”报文首部“**
一个较大的数据被分为多个分组时,为了表明是原始数据的哪一部分,就有必要将分组的序号写入包中。接收端会根据这个序号,再将每个分组按照序号重新分配。
通信协议中通常会规定报文首部应该写入哪些信息、如何处理。
OSI七层模型
OSI参考模型将通信功能分为7个分层,称作OSI参考模型。OSI协议以OSI参考模型为基础界定了每个阶层的协议和每个阶层之间的接口标准。
物理层中,将数据0、1转换为电压和脉冲光传输给物理的传输介质,而相互直连的设备之间使用地址实现传输。这种地址称为MAC地址(物理地址或者硬件地址)。
应用层
为应用层序提供服务并规定应用程序中通信相关的细节,包括文件传输、电子邮件、远程登录等协议。
表示层
将应用处理的信息转换为适合网络传输的格式,或来自下一层的数据转换为上层能处理的格式。
会话层
负责建立和断开通信连接,以及数据的分割等数据传输相关的管理。
传输层(4~7层交换机处理传输层以上网络传输)
起着可靠传输的作用,只在通信双方节点上处理无需路由器上处理。
网络层(路由器/3层交换机)
将数据传输到目标地址。目标地址可以是多个网络通过路由器连接而成的某一个地址。
数据链路层(网桥/2层交换机)
负责将物理层面上互连的、节点之间的通信传输。例如一个以太网相连的2个节点之间的通信。
物理层(中继器物理层上延长设备)
负责0、1比特流与电压高低、光亮灭之间的转换。
网络层与数据链接层都是基于目标地址将数据发送给接收端,但是网络层负责将整个数据发送给最终目标地址,而数据链接层则只负责发送一个分段内的数据。
7层之间通信:每个分层上,在处理由上一层传过来的数据时可以附加上当前封层协议所必须的首部信息,然后接收端对收到的数据进行数据首部与内容的分离,再转发给上一层,并最终将发送端的数据恢复为原状。
地址具有唯一性和层次性。一个地址必须明确表示也给主体对象。
TCP/IP四层/五层模型
网络通信中,数据从上层到下层交付时,要进行封装;同理,当目标主机接收到数据时,数据由下层传递给上层时需要进行拆封。这就是数据的封装与拆封。数据的封装过程如下图所示:
这就是网络数据的发送过程,从图中可以看到,各层协议均会对数据进行相应的封装,可以概括为 TCP/IP 模型中的各层协议对数据进行封装的过程。
IP地址
Internet 依靠 TCP/IP 协议,在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的主机之间的互联。IP是实现多个数据链路之间的通信协议
IP相当于OSI参考模型中的第三层–网络层。网络层可以跨越不同的数据链路,即使是不同的数据链路上也能实现两端节点之间的数据包传输。
IP面向无连接。即在发包之前,不需要建立与对端目标地址之间的连接。上层如果遇到需要发送给IP的数据,该数据会立即被压缩成IP包发送出去。面向无连接为了简化和提速。
在 Internet 上,每一个节点都依靠唯一的 IP 地址相互区分和相互联系, IP 地址用于标识互联网中的每台主机的身份,设计人员为每个接入网络中的主机都分配一个 IP 地址(Internet Protocol Address),只有合法的 IP 地址才能接入互联网中并且与其他主机进行网络通信, IP 地址是软件地址,不是硬件地址,硬件 MAC 地址是存储在网卡中的,应用于局域网中寻找目标主机。
IP 地址中的 32 位实际上包含 2 部分,分别为(网络标识)网络地址和(主机标识)主机地址,可通过子网掩码来确定网络地址和主机地址分别占用多少位。 网络标识在数据链路的每个段配置不同的值。网络标识必须保证互相连接的每个段的地址不相重复。而相同段内相连的主机必须有相同的网络地址。IP地址的主机标识则不允许在同一个网段内重复出现。
根据 IP 地址中网络地址和主机地址两部分分别占多少位的不同,将 IP 地址划分为 5 类,分别为 A、B、 C、 D、 E 五类
A 类 IP 地址
从上图中可以看到,一个 A 类 IP 地址由 1 个字节网络地址和 3 个字节主机地址组成,而网络地址的最高位必须为 0,因此可知,网络地址取值范围为 0~127,一共 128 个网络地址(一个字节8位)。当然,这 128 个网络地址中,其中 3 个网络地址用作特殊用途,因此可用的网络地址有 125 个。
(1)、 A 类地址的第一字节为网络地址,其它 3 个字节为主机地址;
(2)、 A 类地址范围为: 1.0.0.1 ~ 127.255.255.254;
(3)、 A 类地址中设有私有地址和保留地址:
①、 10.X.X.X 是私有地址,所谓私有地址就是在互联网中不能使用,而被用在局域网中使用的地址。
②、 127.X.X.X 是保留地址,用作循环测试使用。
B 类 IP 地址
一个 B 类 IP 地址由 2 个字节的网络地址和 2 个字节的主机地址组成,网络地址的最高位必须是“10”,因此,网络地址第一个字节的取值范围为 128~191, IP 地址范围从 128.0.0.0 到 191.255.255.255。对于 B 类地址来说,一共拥有 16384 个网络地址,其中可用的网络地址有 16382 个,每个网络地址能容纳约 6 万(2^16-2=65534)多个主机。
(1)、 B 类地址中第 1 字节和第 2 字节为网络地址,其它 2 个字节为主机地址。
(2)、 B 类地址范围: 128.0.0.1 ~ 191.255.255.254。
(3)、 B 类地址中设有私有地址和保留地址:
①、 172.16.0.0 ~ 172.31.255.255 是私有地址
②、 169.254.X.X 是保留地址。如果你的 IP 地址是自动获取 IP 地址,而你在网络上又没有找到可用的DHCP 服务器。就会得到其中一个 IP。
C 类 IP 地址
一个 C 类 IP 地址由 3 字节的网络地址和 1 字节的主机地址组成,网络地址的最高位必须是“110”,因此 C 类 IP 地址的第一个字节的取值范围为 192~223。范围从 192.0.0.0 到 223.255.255.255,网络地址可达209 万余个,每个网络地址能容纳 254 个主机。
(1)、 C 类地址第 1 字节、第 2 字节和第 3 个字节为网络地址,第 4 个个字节为主机地址。另外第 1 个字节的高三位固定为 110。
(2)、 C 类地址范围为: 192.0.0.1 ~ 223.255.255.254。
(3)、 C 类地址中的私有地址: 192.168.X.X 是私有地址。
D 类 IP 地址
D 类 IP 地址第一个字节以“1110”开始,它是一个专门保留的地址,它并不指向特定的网络,目前这一类地址被用在多点广播(多播, Multicast),多点广播地址用来一次寻址一组计算机,它标识共享同一协议的一组计算机。
(1)、 D 类地址不分网络地址和主机地址,它的第 1 个字节的高四位固定为 1110。
(2)、 D 类地址范围: 224.0.0.1 ~ 239.255.255.254。
E 类 IP 地址
E 类 IP 地址以“llll0”开始,为将来使用保留。全零(“0.0.0.0” )地址对应于当前主机。全“1”的 IP 地址(“255.255.255.255” )是当前子网的广播地址。
(1)、 E 类地址也不分网络地址和主机地址,它的第 1 个字节的前五位固定为 11110。
(2)、 E 类地址范围: 240.0.0.1 ~ 255.255.255.254。特殊的 IP 地址
特殊地址
这些 IP 地址不能分配给任何一个网络的主机使用。
直接广播地址
在不同网络之间的广播叫做直接广播。
直接广播(Direct Broadcast Address):向某个网络上所有的主机发送报文。 TCP/IP 规定,主机号各位全部为“1”的 IP 地址用于广播,叫作广播地址。譬如一个 IP 地址是 192.168.0.181,这是一个 C 类地址,所以它的主机号只有一个字节,那么对主机号全取 1 得到一个广播地址 192.168.0.255,向这个地址发送数据就能让同一网络下的所有主机接收到。
A、 B、 C 三类地址的广播地址结构如下:
⚫ A 类地址的广播地址为: XXX.255.255.255(XXX 为 A 类地址中网络地址对应的取值范围,譬如:120.255.255.255)。
⚫ B 类地址的广播地址为: XXX.XXX.255.255( XXX 为 B 类地址中网络地址的取值范围,譬如139.22.255.255)。
⚫ C 类地址的广播地址为: XXX.XXX.XXX.255(XXX 为 C 类地址中网络地址的取值范围,譬如203.120.16.255)。
受限广播地址
直接广播要求发送方必须广播网络对应的网络号。但有些主机在启动时,往往并不知道本网络的网络号,这时候如果想要向本网络广播,只能采用受限广播地址(Limited Broadcast Address)。
受限广播地址是在本网络内部进行广播的一种广播地址, TCP/IP 规定, 32 比特全为“1”的 IP 地址用于本网络内的广播,也就是 255.255.255.255。
多播地址
多播地址用在一对多的通信中,即一个发送者,多个接收者,不论接受者数量的多少,发送者只发送一次数据包。多播地址属于 D 类地址, D 类地址只能用作目的地址,而不能作为主机中的源地址。
环回地址
环回地址(Loopback Address)是用于网络软件测试以及本机进程之间通信的特殊地址。把 A 类地址中的 127.XXX.XXX.XXX 的所有地址都称为环回地址,主要用来测试网络协议是否工作正常的作用。比如在电脑中使用 ping 命令去 ping 127.1.1.1 就可以测试本地 TCP/IP 协议是否正常。不能将环回地址作为任何一台主机的 IP 地址使用。
0.0.0.0 地址
IP 地址 32bit 全为 0 的地址(也就是 0.0.0.0)表示本网络上的本主机,只能用作源地址。
0.0.0.0 是不能被 ping 通的,在服务器中, 0.0.0.0 并不是一个真实的的 IP 地址,它表示本机中所有的IPv4 地址。监听 0.0.0.0 的端口,就是监听本机中所有 IP 的端口。
如何判断两个 IP 地址是否处于同一个子网,可通过网络标识来进行判断,网络标识定义如下:
网络标识 = IP 地址 & 子网掩码
一样就是处于同一个网络内。
子网与子网掩码
现在一个IP地址的网络标识和主机标识已不再受限与该地址的类别,而是一个叫做”子网掩码“的识别码通过子网网络地址细分比A类、B类、C类更小粒度的网络。这种方式实际上就是将原来A类、B类、C类等分类中的地址部分用于子网地址,可以将原网络分为多个物理网络的一种机制。
TCP/IP协议
TCP/IP协议是一个协议族,包含了众多的协议,比如HTTP、FTP、MQTT、TCP、UDP等等。
HTTP协议
HTTP超文本传输协议,HTTP是万维网数据通信的基础。HTTP应用是最基础的。HTTP协议工作于客户端(用户)、服务器端(网站)模式下,浏览器作为HTTP客户端通过URL(URL是web页的地址),向HTTP服务器端即web服务器发送请求。
FTP协议
FTP 协议的英文全称为 File Transfer Protocol,简称为FTP,它是一种文件传输协议,从一个主机向一个主机传输文件的协议。 FTP 协议同样也是基于客户端-服务器模式,在客户端和服务器之间进行文件传输,一般用在两个主机间的通信,比如虚拟机的Ubuntu和Windows间进行传输数据就是使用FTP协议。
FTP 除了基本的文件上传/下载功能外,还有目录操作、权限设置、身份验证等机制,许多网盘的文件传输功能都是基于 FTP 实现的。
TCP协议
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于 IP 的传输协议。TCP 协议工作在传输层,对上服务 socket 接口,对下调用 IP 层(网络层)。
①、 TCP 协议工作在传输层,对上服务 socket 接口,对下调用 IP 层;
②、 TCP 是一种面向连接的传输协议,通信之前必须通过三次握手与客户端建立连接关系后才可通信;
③、 TCP 协议提供可靠传输,不怕丢包、乱序。
TCP 协议如何保证可靠传输?
①、 TCP 协议采用发送应答机制,即发送端发送的每个 TCP 报文段都必须得到接收方的应答,才能认为这个 TCP 报文段传输成功。
②、 TCP 协议采用超时重传机制,发送端在发送出一个 TCP 报文段之后启动定时器,如果在定时时间内未收到应答,它将重新发送该报文段。
③、由于 TCP 报文段最终是以 IP 数据报发送的,而 IP 数据报到达接收端可能乱序、重复、所以 TCP协议还会将接收到的 TCP 报文段重排、整理、再交付给应用层。
TCP 协议的特点:
⚫ 面向连接的
TCP 是一个面向连接的协议,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一个 TCP连接,否则将无法发送数据,通过三次握手建立连接。
⚫ 确认与重传
当数据从主机 A 发送到主机 B 时,主机 B 会返回给主机 A 一个确认应答; TCP 通过确认应答 ACK 实现可靠的数据传输。当发送端将数据发送出去之后会等待对端的确认应答。如果有确认应答,说明数据已经成功到达对端。反之,数据丢失的可能性比较大。
在一定的时间内如果没有收到确认应答,发送端就可以认为数据已经丢失,并进行重发。由此,即使产生了丢失,仍然可以保证数据能够到达对端,实现可靠传输。
⚫ 全双工通信
TCP 连接一旦建立,就可以在连接上进行双向的通信。任何一个主机都可以向另一个主机发送数据,数据是双向流通的,所以 TCP 协议是一个全双工的协议。
⚫ 基于字节流而非报文
将数据按字节大小进行编号,接收端通过 ACK 来确认收到的数据编号,通过这种机制能够保证 TCP 协议的有序性和完整性,因此 TCP 能够提供可靠性传输。
⚫ 流量控制(滑动窗口协议)
TCP 流量控制主要是针对接收端的处理速度不如发送端发送速度快的问题,消除发送方使接收方缓存溢出的可能性。 TCP 流量控制主要使用滑动窗口协议,滑动窗口是接受数据端使用的窗口大小,用来告诉发送端接收端的缓存大小,以此可以控制发送端发送数据的大小,从而达到流量控制的目的。这个窗口大小就是我们一次传输几个数据。对所有数据帧按顺序赋予编号,发送方在发送过程中始终保持着一个发送窗口,只有落在发送窗口内的帧才允许被发送;同时接收方也维持着一个接收窗口,只有落在接收窗口内的帧才允许接收。这样通过调整发送方窗口和接收方窗口的大小可以实现流量控制。
⚫ 差错控制
TCP 协议除了确认应答与重传机制外, TCP 协议也会采用校验和的方式来检验数据的有效性,主机在接收数据的时候,会将重复的报文丢弃,将乱序的报文重组,发现某段报文丢失了会请求发送方进行重发,因此在 TCP 往上层协议递交的数据是顺序的、无差错的完整数据。
⚫ 拥塞控制
如果网络上的负载(发送到网络上的分组数)大于网络上的容量(网络同时能处理的分组数),就可能引起拥塞,判断网络拥塞的两个因素:延时和吞吐量。拥塞控制机制是:开环(预防)和闭环(消除)。
流量控制是通过接收方来控制流量的一种方式;而拥塞控制则是通过发送方来控制流量的一种方式。
TCP 发送方可能因为 IP 网络的拥塞而被遏制, TCP 拥塞控制就是为了解决这个问题(注意和 TCP 流量控制的区别)。
TCP 拥塞控制的几种方法:慢启动,拥塞避免,快重传和快恢复。
字节流和报文流的定义与区别
流是全双工的处理过程,它是内核中驱动程序和用户进程之间的数据传输通道。流在I/O系统中是一种I/O机制和功能,不是一个物理设备的概念。字节流是最基本的,所有的InputStrem和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的。
报文是网络中交换与传输的数据单元。报文包含了将要发送的完整的数据信息,其长短很不一致。(可分为自由报文和数字报文)
报文也是网络传输的单位,传输过程中会不断的封装成分组、包、帧来传输,封装的方式就是添加一些信息段,那些就是报文头以一定格式组织起来的数据。
TCP报文格式
当数据由上层发送到传输层时,数据会被封装为 TCP 数据段,我们将其称为 TCP 报文(或 TCP 报文段), TCP 报文由 TCP 首部+数据区域组成,一般 TCP 首部通常为 20 个字节大小 。
源端口号和目标端口号
源端口号和目标端口号各占 2 个字节,一个 4 个字节,每个 TCP 报文都包含源主机和目标主机的端口号,用于寻找发送端和接收端应用进程,这两个值加上 IP 首部中的源 IP 地址和目标 IP 地址就能确定唯一一个 TCP 连接。**有时一个 IP 地址和一个端口号也称为 socket(插口)。**
序号
占 4 个字节,用来标识从 TCP 发送端向 TCP 接收端发送的数据字节流,它的值表示在这个报文段中的第一个数据字节所处位置码,根据接收到的数据区域长度,就能计算出报文最后一个数据所处的序号,因为TCP 协议会对发送或者接收的数据进行编号(按字节的形式),那么使用序号对每个字节进行计数,就能很轻易管理这些数据。
在 TCP 传送的数据流中,每一个字节都有一个序号。例如,一报文段的序号为 300,而且数据共 100 字节,则下一个报文段的序号就是 400;序号是 32bit 的无符号数,序号到达 2^32-1 后从 0 开始。 确认序号
确认序号占 4 字节,是期望收到对方下次发送的数据的第一个字节的序号,也就是期望收到的下一个
报文段的首部中的序号;确认序号应该是上次已成功收到数据字节序号+1。只有 ACK 标志为 1 时,确认序号才有效。 TCP 为应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输,因此确认序号通常会与反向数据(即接收端传输给发送端的数据)封装在同一个报文中(即捎带),所以连接的每一端都必须保持每个方向上的传输数据序号准确性。
首部长度
首部长度字段占 4 个 bit 位,它指出了 TCP 报文段首部长度,以字节为单位,最大能记录 15*4=60 字
节的首部长度,因此, TCP 报文段首部最大长度为 60 字节。在字段后接下来有 6bit 空间是保留未用的,供以后应用,现在置为 0。
6 个标志位: URG/ACK/PSH/RST/SYN/FIN
保留位之后有 6 个标志位,分别如下:
①、 URG: 首部中的紧急指针字段标志,如果是 1 表示紧急指针字段有效。
②、 ACK: 只有当 ACK=1 时,确认序号字段才有效。
③、 PSH: 当 PSH=1 时,接收方应该尽快将本报文段立即传送给其应用层。
④、 RST: 当 RST=1 时,表示出现连接错误,必须释放连接,然后再重建传输连接。复位比特还用来
拒绝一个不法的报文段或拒绝打开一个连接。
⑤、 SYN: SYN=1, ACK=0 时表示请求建立一个连接,携带 SYN 标志的 TCP 报文段为同步报文段。
⑥、 FIN: 为 1 表示发送方没有数据要传输了,要求释放连接。
窗口大小
占用 2 个字节大小,表示从确认号开始,本报文的发送方可以接收的字节数,即接收窗口大小,用于流量控制。
校验和
对整个的 TCP 报文段,包括 TCP 首部和 TCP 数据,以 16 位字进行计算所得。这是一个强制性的字段。
紧急指针
本报文段中的紧急数据的最后一个字节的序号。
选项
选项字段的大小是不确定的,最多 40 字节
建立TCP连接:三次握手
TCP 协议是一个面向连接的协议,双方在进行网络通信之间,都必须先在双方之间建立一条连接,俗称“握手”, 三次握手”其实是指建立 TCP 连接的一个过程,通信双方建立一个 TCP 连接需要经过“三次握手”这样一个过程。
首先建立连接的过程是由客户端发起,而服务器会时刻监听、等待着客户端的连接,其示意图如下
TCP 连接一般来说会经历以下过程:
⚫ 第一次握手
客户端将 TCP 报文标志位 SYN 置为 1,随机产生一个序号值 seq=J,保存在 TCP 首部的序列号(Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入 SYN_SENT 状态,等待服务器端确认。
⚫ 第二次握手
服务器端收到数据包后由标志位 SYN=1 知道客户端请求建立连接,服务器端将 TCP 报文标志位 SYN和 ACK 都置为 1, ack=J+1,随机产生一个序号值 seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD 状态。
⚫ 第三次握手
客户端收到确认后,检查 ack 是否为 J+1, ACK 是否为 1,如果正确则将标志位 ACK 置为 1, ack=K+1,并将该数据包发送给服务器端,服务器端检查 ack 是否为 K+1, ACK 是否为 1,如果正确则连接建立成功,客户端和服务器端进入 ESTABLISHED 状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
关闭 TCP 连接:四次挥手
除了“三次握手”,还有“四次挥手”,“四次挥手”(有一些书也会称为四次握手)其实是指关闭 TCP
连接的一个过程,当通信双方需要关闭 TCP 连接时需要经过“四次挥手”这样一个过程。四次挥手即终止 TCP 连接,就是指断开一个 TCP 连接时,需要客户端和服务端总共发送 4 个包以确认连接的断开。在 socket 编程中,这一过程由客户端或服务端任一方执行 close 来触发。
由于 TCP 连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送
任务后,发送一个 FIN 来终止这一方向的连接,收到一个 FIN 只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个 TCP 连接上仍然能够发送数据,直到这一方向也发送了 FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
挥手请求可以是 Client 端,也可以是 Server 端发起的 ,这是假设由client端发起的。
⚫ 第一次挥手
Client 端发起挥手请求,向 Server 端发出一个 FIN 报文段主动进行关闭连接,此时报文段的 FIN 标志
位被设置为 1。此时, Client 端进入 FIN_WAIT_1 状态,这表示 Client 端没有数据要发送给 Server 端了。
⚫ 第二次挥手
Server 端收到了 Client 端发送的 FIN 报文段,向 Client 端返回一个 ACK 报文段,此时报文段的 ACK
标志位被设置为 1。 ack 设为 seq 加 1, Client 端进入 FIN_WAIT_2 状态, Server 端告诉 Client 端,我确认并
同意你的关闭请求。
⚫ 第三次挥手
Server 端向 Client 端发送一个 FIN 报文段请求关闭连接,此时报文段的 FIN 标志位被设置为 1,同时
Client 端进入 LAST_ACK 状态。
⚫ 第四次挥手
Client 端收到 Server 端发送的 FIN 报文段后,向 Server 端发送 ACK 报文段(此时报文段的 ACK 标志
位被设置为 1),然后 Client 端进入 TIME_WAIT 状态。 Server 端收到 Client 端的 ACK 报文段以后,就关闭连接。此时, Client 端等待 2MSL 的时间后依然没有收到回复,则证明 Server 端已正常关闭,那好, Client端也可以关闭连接了。
TCP状态说明
建立连接和断开连接以及数据传输过程会呈现不同状态:
⚫ CLOSED 状态: 表示一个初始状态。
⚫ LISTENING 状态: 这是一个非常容易理解的状态,表示服务器端的某个 SOCKET 处于监听状态,监听客户端的连接请求,可以接受连接了。譬如服务器能够提供某种服务,它会监听客户端 TCP端口的连接请求,处于 LISTENING 状态,端口是开放的,等待被客户端连接。
⚫ SYN_SENT 状态(客户端状态): 当客户端调用 connect()函数连接时,它首先会发送 SYN 报文给服务器请求建立连接,因此也随即它会进入到了 SYN_SENT 状态,并等待服务器的发送三次握手中的第 2 个报文。 SYN_SENT 状态表示客户端已发送 SYN 报文。
⚫ SYN_REVD 状态(服务端状态): 这个状态表示服务器接受到了 SYN 报文,在正常情况下,这个状态是服务器端的 SOCKET 在建立 TCP 连接时的三次握手过程中的一个中间状态, 很短暂,基本上用 netstat 你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次 TCP 握手过程中最后一个 ACK 报文不予发送。因此这种状态时,当收到客户端的 ACK 报文后,它会进入到 ESTABLISHED 状态。
⚫ ESTABLISHED 状态: 这个容易理解了,表示连接已经建立了。
⚫ FIN_WAIT_1 和 FIN_WAIT_2 状态: 其实 FIN_WAIT_1 和 FIN_WAIT_2 状态的真正含义都是表示等待对方的 FIN 报文。而这两种状态的区别是: FIN_WAIT_1 状态实际上是当 SOCKET 在ESTABLISHED 状态时,它想主动关闭连接,向对方发送了 FIN 报文,此时该 SOCKET 即进入到FIN_WAIT_1 状态。而当对方回应 ACK 报文后,则进入到 FIN_WAIT_2 状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应 ACK 报文,所以 FIN_WAIT_1 状态一般是比较难见到的,而 FIN_WAIT_2 状态还有时常常可以用 netstat 看到。
⚫ TIME_WAIT 状态: 表示收到了对方的 FIN 报文,并发送出了 ACK 报文,就等 2MSL 后即可回到 CLOSED 可用状态了。如果 FIN_WAIT_1 状态下,收到了对方同时带 FIN 标志和 ACK 标志的报文时,可以直接进入到 TIME_WAIT 状态,而无须经过 FIN_WAIT_2 状态。
⚫ CLOSE_WAIT 状态: 这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方 close 一个SOCKET 后发送 FIN 报文给自己,你系统毫无疑问地会回应一个 ACK 报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close 这个 SOCKET,发送 FIN 报文给对方,也即关闭连接。所以你在 CLOSE_WAIT 状态下,需要完成的事情是等待你去关闭连接。
⚫ LAST_ACK 状态: 它是被动关闭一方在发送 FIN 报文后,最后等待对方的 ACK 报文。当收到 ACK报文后,也即可以进入到 CLOSED 状态了。
UDP协议
UDP(用户数据报协议)是一种无连接、不可靠的协议,同时它也工作在传输层,它只是简单地从一端主机到另一个主机的数据传输功能,这些数据通过IP层发送,在网络中传输,到达目标主机的顺序是无法预知的。
UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务,并且它是将应用程序发来的数据在收到的一刻,立刻按照原样发送到网络上的一种机制。传输途中即使丢包,UDP也不负责重发。
由于UDP面向无连接,它可以随时发送数据。再加上本身UDP本身处理简单高效,因此经常用于几个方面:
包总量较少的通信(DNS、SNMP等)
视频、音频等多媒体通信(即时通信)
限定于LAN等特定网络中的应用通信
广播通信(广播、多播)
UDP具有以下几个特点:
①、无连接、不可靠;
②、尽可能提供交付数据服务,出现差错直接丢弃,无反馈;
③、面向报文,发送方的 UDP 拿到上层数据直接添加个 UDP 首部,然后进行校验后就递交给 IP 层,而接收的一方在接收到 UDP 报文后简单进行校验,然后直接去除数据递交给上层应用;
④、速度快,因为 UDP 协议没有 TCP 协议的握手、确认、窗口、 重传、拥塞控制等机制, UDP 是一个无状态的传输协议,所以它在传递数据时非常快,即使在网络拥塞的时候 UDP 也不会降低发送的数据。
端口号
数据链路和IP中的地址分别指的是MAC地址和IP地址。前者用来识别同一链路中的不同的计算机,后者用来识别TCP/IP网络中互连的主机和路由器。在传输层中也有类似于地址的概念,这就是端口号,端口号用来识别同一台计算机中进行通信的不同应用程序,也叫做程序地址。
一个计算机上同时可以运行多个程序,例如web服务器、电子邮箱客户端等都可以同时运行,传输层协议正式利用端口识别号识别本机中正在通信的应用程序,并准确将数据传输。
TCP/IP或者UDP/IP通信采用5个信息来识别一个通信,它们是源IP地址、目标IP地址、协议号、源端口号、目标端口号,只要其中一项不同,就是其他的通信。
端口号如何确定
确定端口号有两种方法:
①标准既定的端口号
也叫静态方法,它只每个应用程序都有其指定的端口号,但并不是说可以使用认识一个端口号,每个端口号都有对应的使用目的。例如HTTP、TELNET、FTP等应用协议中使用的端口号就是固定的。这些端口号就是
②时序分配法
此时服务端也必要确定监听端口号,但是接收服务的客户端也没必要确定端口号。这种情况下客服端应用程序可以完全不用自己设置端口号,而全权交给操作系统分配。
常见服务器具有特定的端口号: