1.前言
1.1 通信协议的必要性:
简单来说,协议就是计算机之间通过网络实现通信时事先达成的一种“约定”;这种“约定”使那些由不同厂商的设备,不同CPU及不同操作系统组成的计算机之间,只要遵循相同的协议就可以实现通信。
协议可以分很多种,每一种协议都明确界定了它的行为规范:2台计算机之间必须能够支持相同的协议,并且遵循相同的协议进行处理,才能实现相互通信。
1.2 通信协议的标准化:
计算机通信诞生之初,系统化与标准化未收到重视,不同厂商只出产各自的网络来实现通信,这样就造成了对用户使用计算机网络造成了很大障碍,缺乏灵活性和可扩展性。
为解决该问题,ISO(国际标准化组织)制定了一个国际标准OSI(开放式通信系统互联参考模型)。TCP/IP并非ISO指定,是由IETF(国际互联网工程任务组)建议、致力推进标准化的一种协议,其中,大学等研究机构和计算机行业是推动标准化的核心力量,现已成为业界标准协议。
2. 什么是 TCP/IP?
概述:
- TCP/IP 是供已连接因特网的计算机进行通信的通信协议。
- TCP/IP 指传输控制协议/网际协议 (Transmission Control Protocol / Internet Protocol)。
- TCP/IP 定义了电子设备(比如计算机)如何连入因特网,以及数据如何在它们之间传输的标准。
详述:
TCP/IP 不是一个协议,而是一个协议族,在 TCP/IP 中包含一系列用于处理数据通信的协议,如下所示:
- TCP (传输控制协议) - 应用程序之间通信
- UDP (用户数据包协议) - 应用程序之间的简单通信
- IP (网际协议) - 计算机之间的通信
- ICMP (因特网消息控制协议) - 针对错误和状态
- DHCP (动态主机配置协议) - 针对动态寻址
3. 协议分层
由于ISO标准中的网络模型是个7层模型,但是由于7层模型对于当时的网络厂商来说太过复杂,很多厂家采用了简化的4层模型来实现网络设备,4层模型也就成了事实的网络标准模型。这也导致很多写计算机网络的书籍中对现有网络的分层依据不同,导致出现了网络7层,5层,4层模型。TCP/IP协议是个4层模型,OSI是7层模型。
3.1 应用层
应用层决定了向用户提供应用服务时通信的活动。TCP/IP 协议族内预存了各类通用的应用服务。比如,FTP(FileTransfer Protocol,文件传输协议)和 DNS(Domain Name System,域名系统)服务就是其中两类。HTTP 协议也处于该层。
3.2 传输层
传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Data Protocol,用户数据报协议)。主要为两台主机上的应用程序提供端到端的通信。
在TCP/IP协议族中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。TCP为两台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。为了提供可靠的服务,TCP采用了超时重传、发送和接收端到端的确认分组等机制。
UDP则为应用层提供一种非常简单的服务。它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。一个数据报是指从发送方传输到接收方的一个信息单元(例如,发送方指定的一定字节数的信息)。UDP协议任何必需的可靠性必须由应用层来提供。
3.3 网络层
网络层又名网络互连层、互联网层,处理分组在网络中的活动,例如分组的选路。在TCP/IP协议族中,网络层协议包括IP协议(网际协议),ICMP协议(Internet互联网控制报文协议),以及IGMP协议(Internet组管理协议)。网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。
3.4 网络接口层
网络接口层也称链路层、数据链路层,用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。
4. IP地址介绍
不同的计算机通过网络进行通信的时候,双方必须知道对方的标识,并且这个标识必须是唯一的,好比发邮件必须知道对方的邮件地址。互联网上每个计算机的唯一标识就是IP地址,如,193.123.10.54。
IP 地址是一个 32 位的地址,这个地址通常分成 4 端,每 8 个二进制为一段,但是为了方便阅读,通常会将每段都转换为十进制来显示,比如大家非常熟悉的 192.168.0.1。
IP 地址分为两个部分:网络 ID+主机 ID,但是具体哪部分属于网络 ID,哪些属于主机 ID 并没有规定.。因为有些网络是需要很多主机的,这样的话代表主机 ID 的部分就要更多,但是有些网络需要的主机很少,这样主机 ID 的部分就应该少一些.
绝大部分 IP 地址属于以下几类
- A 类地址:IP 地址的前 8 位代表网络 ID ,后 24 位代表主机 ID。
- B 类地址:IP 地址的前 16 位代表网络 ID ,后 16 位代表主机 ID。
- C 类地址:IP 地址的前 24 位代表网络 ID ,后 8 位代表主机 ID。
- 如果 32 位的 IP 地址以 0 开头,那么它就是一个 A 类地址。
- 如果 32 位的 IP 地址以 10 开头,那么它就是一个 B 类地址。
- 如果 32 位的 IP 地址以 110 开头,那么它就是一个 C 类地址。
那么转化为十进制(四段)的话,我们就能以第一段中的十进制数来区分 IP 地址到底是哪类地址了。
注意:
- 十进制第一段大于 223 的属于 D 类和 E 类地址,这两类比较特殊也不常见,这里就不做详解介绍了;
- 每一类都有一些排除地址,这些地址并不属于该类,他们是在一些特殊情况使用地址;
- 除了这样的方式来划分网络,我们还可以把每个网络划分为更小的网络块,称之为子网;
- 全是 0 的主机 ID 代表网络本身,比如说 IP 地址为 130.100.0.0 指的是网络 ID 为130.100 的 B 类地址。
- 全是 1 的主机 ID 代表广播,是用于向该网络中的全部主机方法消息的。 IP 地址为 130.100.255.255 就是网络 ID 为 130.100 网络的广播地址(二进制 IP 地址中全是 1 ,转换为十进制就是 255 )。
- 以十进制 127 开头的地址都是环回地址。目的地址是环回地址的消息,其实是由本地发送和接收的。主要是用于测试 TCP/IP 软件是否正常工作。我们用 ping 功能的时候,一般用的环回地址是 127.0.0.1。
我们可以发现,通过IP地址的网络号和主机号已经可以识别网络接口,进而访问主机,但是人们最喜欢还是使用主机名,所以我们需要提供一个:域名系统(DNS),它给我们提供了主机名和IP地址之间的映射信息。
5.两种传输方式
网络通信科根据数据发送方法进行多种分类,分类方法很多,下面列举两种常见的:
5.1 面向有连接型
发送数据之前,需要在收发主机之间建立一条通信线路,在通信传输前后,专门进行建立和断开连接的处理,如果与对端之间无法通信,可避免发送无谓的数据
5.2面向无连接型
这种类型不要求建立和断开连接,发送端可任何时候发送数据,接收端也不知道自己何时从哪里接受数据,这种情况下,接收端需要时常确认是否收到数据,彼此也不需要确认对方是否存在
6. TCP/IP通信中的三次握手,四次挥手
TCP中两个序号和三个标志位的含义:
- ACK:确认位,确认序号有效,只有ACK=1时,ack才起作用。正常通信时,ACK=1,第一次发起请求是因为没有需要确认接收的数据,所以ACK为0.
- SYN:发起了一个新连接,同步位u,用于在建立连接时同步序号。刚开始建立连接时并没有历史接收的数据,所以ack也无法设置,这时按照正常的机制就无法运行了,SYN的作用就是来解决这个问题的。当接收端接收到SYN=1的报文时,就会直接将ack设置为接收到seq+1的值,注意这里的值并不是校验后设置的,而是根据SYN直接设置的,这样正常的机制就可以运行了,所以SYN叫同步位。SYN在前两次握手时都为1,这是因为通信的双方的ack都需要设置一个初始值。
- FIN:终止位,用于在数据传输完毕后释放连接。
- RST:重置连接
6.1 三次握手的过程(客户端我们用A表示,服务器端用B表示)
- 在建立连接之前,B先创建TCB(传输控制块),准备接受客户进程的连接请求,处于LISTEN(监听)状态
- A首先创建TCB,然后向B发出连接请求,SYN置1,同时选择初始序号seq=x,进入SYN-SEND(同步已发送)状态
- B收到连接请求后向A发送确认,SYN置1,ACK置1,同时产生一个确认序号ack=x+1。同时随机选择初始序号seq=y,进入SYN-RCVD(同步收到)状态
- A收到确认连接请求后,ACK置1,确认号ack=y+1,seq=x+1,进入到ESTABLISHED(已建立连接)状态。向B发出确认连接,最后B也进入到ESTABLISHED(已建立连接)状态。
- 建立连接时,客户端发送SYN包(SYN=i)到服务器,并进入到SYN-SEND状态,等待服务器确认
- 服务器收到SYN包,必须确认客户的SYN(ack=i+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器进入SYN-RECV状态
- 客户端收到服务器的SYN+ACK包,向服务器发送确认报ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
#netstat -nap | grep SYN_RECV
6.2 四次分手的过程(客户端我们用A表示,服务器端用B表示)
- A发送一个FIN,用来关闭A到B的数据传送,A进入FIN_WAIT_1状态。
- B收到FIN后,发送一个ACK给A,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),B进入CLOSE_WAIT状态。
- B发送一个FIN,用来关闭B到A的数据传送,B进入LAST_ACK状态。
- A收到FIN后,A进入TIME_WAIT状态,接着发送一个ACK给B,确认序号为收到序号+1,B进入CLOSED状态,完成四次挥手。
- 客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送(报文段4)。
- 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
- 服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)。
- 客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。
- 为了保证A发送的最后一个ACK报文段能够到达B
- 防止“已失效的连接请求报文段”出现在本连接中
- 客户端发个请求“开门呐,我要进来”给服务器
- 服务器发个“进来吧,我去给你开门”给客户端
- 客户端有很客气的发个“谢谢,我要进来了”给服务器
- 客户端发个“时间不早了,我要走了”给服务器,等服务器起身送他
- 服务器听到了,发个“我知道了,那我送你出门吧”给客户端,等客户端走
- 服务器把门关上后,发个“我关门了”给客户端,然后等客户端走(尼玛~矫情啊)
- 客户端发个“我知道了,我走了”,之后自己就走了
7. 特别致谢
本文参考并引用了以下文献:
1. https://blog.csdn.net/u011318165/article/details/48102939