计算机网络基础篇
1.TCP/IP网络模型分层
网络模型划分主要有3种,如下图所示
越往下越偏向硬件
为什么要进行分层?
为了便于维护和扩展,程序的功能之间应该是解耦的。因此,复杂的程序都要分层,这是程序设计的要求。
分层的好处?
1.各层之间是独立的。某一层并不需要知道它的下一层是如何实现的,而仅仅需要知道该层通过层间的接口所提供的服务。这样,整个问题的复杂程度就下降了。 2.灵活性好。当任何一层发生变化时,只要层间接口关系保持不变,则在这层以上或以下各层均不受影响。排除问题时也只需要考虑这一层单独的问题即可。 3.易于实现和维护。进行调试和维护时,可以对每一层进行单独的调试,避免了出现找不到问题、解决错问题的情况
我们先简单说一下TCP/IP协议栈的各个的功能
1.应用层(Application Layer)
举一个例子吧,比如你去送快递,我们要把一个物品寄送给别人,其中我们要寄送的这个物品就属于应用层,再比如我们一个APP里面的应用的数据
至于外卖怎么送给别人还有怎么让APP中的应用请求信息这些我们不管,这些属于传输层哥们干的活
我感觉小林coding里面有几句话说的特别好
所以,应用层只需要专注于为用户提供应用功能,比如 HTTP、FTP、Telnet、DNS、SMTP等。
应用层是不用去关心数据是如何传输的,就类似于,我们寄快递的时候,只需要把包裹交给快递员,由他负责运输快递,我们不需要关心快递是如何被运输的。
而且应用层是工作在操作系统中的用户态,传输层及以下则工作在内核态。
2.传输层(Transport Layer)
在上面讲应用层的时候我们稍微提了一嘴传输层,我个人理解的传输层就是接收应用层传递过来的数据
传输层(Transport Layer)是为应用层提供网络支持的。
我们所熟知的两个协议TCP协议和UDP协议就是属于传输层传输的协议
韩顺平讲java的网络通信的时候,是这么形容TCP与UDP的
比如你去一个厕所上厕所,你要先隔着门问能不能进去,当厕所里面的人回应了你可以进去之后,你才可以进去,这个是TCP
但是如果你隔着门问能不能进去,还没等别人说话呢,你就破门而入了,这就是UDP
小林coding给出的理解是
TCP 的全称叫传输控制协议(Transmission Control Protocol),大部分应用使用的正是 TCP 传输层协议,比如 HTTP 应用层协议。TCP 相比 UDP 多了很多特性,比如流量控制、超时重传、拥塞控制等,这些都是为了保证数据包能可靠地传输给对方。
UDP 相对来说就很简单,简单到只负责发送数据包,不保证数据包是否能抵达对方,但它实时性相对更好,传输效率也高。当然,UDP 也可以实现可靠传输,把 TCP 的特性在应用层上实现就可以,不过要实现一个商用的可靠 UDP 传输协议,也不是一件简单的事情。
所以TCP与UDP对比起来,TCP的可靠性更高一点,但是相应的实时性,传输效率就不如UDP
2.1TCP段
我们之所以要引入TCP段,是因为有时候我们传递的数据很大,如果传输直接传输这么大的数据很容易控制不好,所以我们选择把这些数据分成若干个小数据一起传输,每个数据都有一个序号和确认号等到都被传输好后,按照序号重新进行排列,把数据组装成原来的那个数据,其中我们把每个分块称为一个 TCP 段(TCPsegment)
这个和之前我在计算机网络概述中的分组交换很像,虽然TCP协议的分节机制确实和分组交换有一定的相似之处,但是它们并不是完全一样的概念。
传输层的数据包大小超过 MSS(TCP 最大报文段长度) ,就要将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块,而不用重新发送整个数据包。
当你的传输层要把数据包传输给其他应用的时候,可能存在多个应用,如果没有一个标志的话可能存在把数据传输给了其他的应用,因此我们定义一个编号负责把这些应用区分开,这个编号就是端口
比如说
- 80:HTTP (HyperText Transfer Protocol)服务端口,用于Web服务器。
- 443:HTTPS (HTTP Secure)服务端口,用于加密的Web服务器。
- 25:SMTP (Simple Mail Transfer Protocol)服务端口,用于邮件服务器。
- 110:POP3 (Post Office Protocol version 3)服务端口,用于接收邮件。
- 143:IMAP (Internet Message Access Protocol)服务端口,用于接收邮件。
- 22:SSH (Secure Shell)服务端口,用于安全的远程登录。
- 21:FTP (File Transfer Protocol)服务端口,用于文件传输。
- 53:DNS (Domain Name System)服务端口,用于域名解析。
- 3306:MySQL数据库服务端口。
- 5432:PostgreSQL数据库服务端口。
而对于浏览器(客户端)中的每个标签栏都是一个独立的进程,操作系统会为这些进程分配临时的端口号。
由于传输层的报文中会携带端口号,因此接收方可以识别出该报文是发送给哪个应用。
3.网络层
我之前一直以为应用层把数据传递给传输层之后传输层就负责把数据给那些应用,但是实际并不是这样的,传输层只能说是传输数据的一种媒介,帮助实现应用到应用的通信,而实际的传输功能就交给下一层,也就是网络层(Internet Layer)。
为什么这么设计呢?因为我们对传输层的要求是简单,高效,专注,但是数据在网络中的传输却是错综复杂的,如果我们让传输层还负责这些东西的话就会丧失掉它的这些特性,所以它只负责当网络传输的媒介而不适合实际进行传输
网络层最常使用的是 IP 协议(Internet Protocol),IP 协议会将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文,如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文。
这个和传输层的TCP段很像,都是为了不让数据过多因而对它们进行拆分
3.1TCP协议与IP协议
TCP协议和IP协议的关系如下
TCP协议是传输层协议,负责提供可靠的数据传输和错误校验机制,确保数据的完整性和正确性。TCP协议将数据分为多个小块进行传输,每个小块称为一个TCP段(TCP segment),每个TCP段都有序号和确认号,确保数据传输的可靠性。(端口)
IP协议是网络层协议,负责将数据包从源主机传输到目的主机,提供了网络互联和路径选择等功能。IP协议将数据分为多个数据包进行传输,每个数据包称为一个IP数据报(IP datagram),每个IP数据报包含了目的地址、源地址、控制信息和数据等内容。(IP)
在TCP/IP协议栈中,TCP段是通过IP协议进行传输的。具体来说,TCP协议将数据分成多个TCP段进行传输,每个TCP段会被封装到一个IP数据报中,并且每个IP数据报会包含目的地址和源地址等控制信息,以确保数据能够正确地传输到目的主机。因此,TCP段和IP协议是密切相关的,TCP协议依赖于IP协议来进行数据传输和路由选择等操作。
差不多就可以理解为TCP协议负责将数据拆分为多个数TCP段,而IP协议负责把这些数据段进行传递
一个IP报文由多个TCP段组成,为了防止IP报文过大,他还会继续进行拆分
小林coding给出下面这个图方便理解
刚才我们说的传输层的端口号是为了把TCP段的信息传递给相应的应用,而用IP协议传递时需要找到相应的设备号,因此,网络层需要有区分设备的编号。
我们一般用 IP 地址给设备进行编号,
所以我们如果要把数据传递给某一个应用,首先通过IP协议找到对应的IP地址,然后通过TCP协议把数据传递给该IP地址相应的端口号
对于 IPv4 协议, IP 地址共 32 位,分成了四段(比如,192.168.100.1),每段是 8 位。只有一个单纯的 IP 地址虽然做到了区分设备,但是寻址起来就特别麻烦,全世界那么多台设备,难道一个一个去匹配?这显然不科学。
因此将IP地址
因此,需要将 IP 地址分成两种意义:
- 一个是网络号,负责标识该 IP 地址是属于哪个「子网」的;
- 一个是主机号,负责标识同一「子网」下的不同主机;
并不是网络号+主机号就构成了IP地址,我们想要算出IP地址的网络号和主机号还需要子网掩码才能算出来
小林coding中有一个例子:
举个例子,比如 10.100.122.0/24,后面的/24
表示就是 255.255.255.0
子网掩码,255.255.255.0 二进制是「11111111-11111111-11111111-00000000」,
255是2的7次方-1,所以255的二进制就是由8个1构成的,这里255.255.255.0有3*8个1共24个1,所以那个就是/24
知道了子网掩码,该怎么计算出网络地址和主机地址呢?
将 10.100.122.2 和 255.255.255.0 进行按位与运算,就可以得到网络号,如下图:
将 255.255.255.0 取反后与IP地址进行进行按位与运算,就可以得到主机号。
所以我们可以总结一下
网络号 | IP地址与掩码与运算 |
---|---|
主机号 | IP地址与掩码的反码与运算 |
为了方便计算,人们制作了一个网络号与主机号计算器,可以方便对网络号和主机号的计算
在寻址的过程中,先匹配到相同的网络号(表示要找到同一个子网),才会去找对应的主机。
除了寻址能力, IP 协议还有另一个重要的能力就是路由。实际场景中,两台设备并不是用一条网线连接起来的,否则的话,比如我在宿舍与你在教室通讯就要用一根很长的网线才可以。
我们通过很多网关、路由器、交换机等众多网络设备连接起来的,那么就会形成很多条网络的路径,因此当数据包到达一个网络节点,就需要通过路由算法决定下一步走哪条路径。
路由器寻址工作中,就是要找到目标地址的子网,找到后进而把数据包转发给对应的网络内。
所以,IP 协议的寻址作用是告诉我们去往下一个目的地该朝哪个方向走,路由则是根据「下一个目的地」选择路径。寻址更像在导航,路由更像在操作方向盘。
3.2梳理一下网络层
我们是通过IP协议来发送IP报文,IP报文里面的数据是由传输层的TCP段组成的
我们需要知道网络号(子网),知道了网络号我们就在那个网络号找相应的主机号。
网络号是用掩码AND IP地址
主机号是用掩码的反码AND IP地址
通过路由器根据目的IP地址和路由表等信息,将数据转发到正确的网络设备上,以便将数据传输到目的主机。
4.网络接口层
生成了 IP 头部之后,接下来要交给网络接口层(Link Layer)在 IP 头部的前面加上 MAC 头部,并封装成数据帧(Data frame)发送到网络上。
我们通过IP地址与掩码可以找到相关的网络号和主机号,按照正常思路就可以根据这两个传递相应数据了
但是在以太网中并不是这样的
以太网就是一种在「局域网」内,把附近的设备连接起来,使它们之间可以进行通讯的技术。
以太网在判断网络包目的地时和 IP 的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,而 MAC 头部就是干这个用的,所以,在以太网进行通讯要用到 MAC 地址。
MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息,我们可以通过 ARP 协议获取对方的 MAC 地址。
所以说,网络接口层主要为网络层提供「链路级别」传输的服务,负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备。
5.总结
综上所述,TCP/IP 网络通常是由上到下分成 4 层,分别是应用层,传输层,网络层和网络接口层。
再给大家贴一下每一层的封装格式:
网络接口层的传输单位是帧(frame),IP 层的传输单位是包(packet),TCP 层的传输单位是段(segment),HTTP 的传输单位则是消息或报文(message)。但这些名词并没有什么本质的区分,可以统称为数据包。
2.键入网址到网页显示,期间发生了什么?
1.HTTP
比如我现在给一段URL
浏览器做的第一件操作就是对这一段URL进行解析
上面的那段URL我们可以如下解析
https+//+www.baidu.com
其中https是URL开头表示访问数据的协议,有http还有https,它们的区别后面再详细的说
//后面的字符串表示服务器的名称
但这里www.baidu.com其实并不是服务器的名称,它被称为域名,因为服务器的太难记了,所以我们一般会选择用域名来弄。
域名或者服务器名称后面的表示数据(文件)的路径名可以被省略,者如上图
当没有路径名时,(比如说上面的https://www.baidu.com,它的后面并没有数据文件的路径名)就代表访问根目录下事先设置的默认文件,也就是 /index.html
或者 /default.html
这些文件,这样就不会发生混乱了。
1.1生产 HTTP 请求信息
对 URL
进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。
2.DNS
我们刚才说https为数据的协议,//后面的表示域名或者服务器的名称,可是我们访问一个网页,还需要获得通信对象的IP地址,这时候我们就需要用到DNS,通过DNS我们可以解析域名来获得IP地址
主要是通过DNS服务器用来保存DNS与对应的IP地址,这就像哈希表一样,有一个键,还有与键对应的值
2.1域名的层级关系
还是比如那个百度
按照我们的思维,那就是越靠近左边,它的范围就越大,比如陕西省西安市,那肯定是陕西省更大,但是域名是由外国人发明的,他们的思维和我们不一样,比如我们是姓在前,名在后;他们和我们相反,是名在前,姓在后
中间是用.隔开,每一个.之间表示不同层次的界限
实际上域名最后还有一个点,比如 www.baidu.com.
,这个最后的一个点代表根域名。
也就是,.
根域是在最顶层,它的下一层就是 .com
顶级域,再下面是 baidu.com
。
我们把.称之为根 DNS 服务器,.com是顶级域DNS服务器,baidu.com是权威DNS服务器
如果你在腾讯云或者其他上面买过域名的话,你会发现,.com即顶级域服务器的价格是最贵的,然后是.cn,还有很多其他的,看起来名字很奇怪的顶级DNS服务器
至于为什么.com是最贵的,那是因为.com可以保证国内国外都可以访问这个网站,但是.cn只有国内才可以访问这个网站,导致了.cn比.com便宜许多
在域名解析的过程,我们可以看作以根DNS服务器为根的一个树状图结构
根域的 DNS 服务器信息保存在互联网中所有的 DNS 服务器中。
这样一来,任何 DNS 服务器就都可以找到并访问根域 DNS 服务器了。
因此,客户端只要能够找到任意一台 DNS 服务器,就可以通过它找到根域 DNS 服务器,然后再一路顺藤摸瓜找到位于下层的某台目标 DNS 服务器。
2.2域名解析的工作流程
- 客户端首先会发出一个 DNS 请求,问 www.baidu.com 的 IP 是啥,并发给本地 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。
- 本地域名服务器收到客户端的请求后,如果缓存里的表格能找到 www.baidu.com,则它直接返回 IP 地址。如果没有,本地 DNS 会去问它的根域名服务器:“老大, 能告诉我 www.baidu.com 的 IP 地址吗?” 根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路。
- 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,说:“www.baidu.com 这个域名归 .com 区域管理”,我给你 .com 顶级域名服务器地址给你,你去问问它吧。”
- 本地 DNS 收到顶级域名服务器的地址后,发起请求问“老二, 你能告诉我 www.baidu.com 的 IP 地址吗?”
- 顶级域名服务器说:“我给你负责 www.baidu.com 区域的权威 DNS 服务器的地址,你去问它应该能问到”。
- 本地 DNS 于是转向问权威 DNS 服务器:“老三,www.baidu.com对应的IP是啥呀?” server.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
- 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
- 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。
我只能说小林coding写的确实很生动且形象,如果用更加简洁的话来形容就是
首先发送DNS请求,现在本地DNS服务器中查找,如果本地DNS服务器的缓存的表格里面没有找到的话,那么就会直接访问根服务器(上面不是说过了嘛,因为根域的DNS服务器的信息保存在了互联网的所有DNS服务器中,所以任意一台DNS服务器都可以访问到根DNS服务器),找到之后,根DNS会判断出顶级域名为多少,并且给出顶级域DNS服务器的地址,收到顶级域服务器的地址后,发起请求,顶级域服务会判断权威域名并给出权威DNS服务器地址,发起请求,这时候权威DNS服务器就会解析你给出的域名,并将对应的IP地址返回给本地DNS服务器,本地DNS再将IP地址返回给客户端,这样客户端与目标建立连接
再给出一张小林coding的图
2.3那是不是每次解析域名都要经过那么多的步骤呢?
首先肯定不是这样的,因为如果这样的话,那我们第一步,从本地DNS服务器的缓存列表中获取就没有必要了
浏览器会先看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去 hosts 文件看,也没有,才会去问本地 DNS 服务器
我们把浏览器的设置打开,然后点击cookie和网站权限
然后我们可以看见Cookie和网站权限上面写着Cookie和已存储数据
2.4HTTP与DNS这两个的过程,数据的传送过程
首先HTTP过程对URL进行解析,解析出域名与访问数据的协议,然后生成HTTP的请求消息,然后在DNS解析的过程中将域名解析为相应的IP地址,给数据包的传送位置指明了方向
3.协议栈
我们通过HTTP解析出域名,访问数据的协议并生成了HTTP的请求消息,再通过DNS解析将域名成功转化成了IP地址,提供了访问的方向
现在我们要通过协议栈将消息成功发送出去
协议栈的内部分为几个部分,分别承担不同的工作。上下关系是有一定的规则的,上面的部分会向下面的部分委托工作,下面的部分收到委托的工作并执行
应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,这两个传输协议会接受应用层的委托执行收发数据的操作。
协议栈的下面一半是用 IP 协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由 IP 负责的。
此外 IP 中还包括 ICMP
协议和 ARP
协议。
ICMP
用于告知网络包传送过程中产生的错误以及各种控制信息。ARP
用于根据 IP 地址查询相应的以太网 MAC 地址。
IP 下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,也就是对网线中的信号执行发送和接收操作。
3.1TCP协议
3.1.1TCP的包头格式
首先源端口号,目的端口号这2个肯定要要,如果没有这两个端口号,数据就不知道应该发给哪个应用。
接下来有包的序号,标识TCP数据流中的每个数据段的顺序,这个是为了解决包乱序的问题。如果不是特别理解的话,等一会儿TCP的三次握手,四次挥手就可以感受它的作用了
确认序列这个看名字就可以理解了,这个就是为了判断接收方有没有收到消息
然后这个上面的URG,ACK,PSH,RST,SYN,FIN属于状态位,(md,看到这个状态位我想到我的操作系统考试了)
SYN | 发起一个连接 |
---|---|
ACK | 回复 |
RST | 重新连接 |
FIN | 是结束连接 |
然后再状态位置的右边有一个窗口大小
TCP 要做流量控制,通信双方各声明一个窗口(缓存大小),标识自己当前能够的处理能力,别发送的太快,撑死我,也别发的太慢,饿死我。
3.1.2TCP中比较重要的包头格式
源端口号 | 发送方的端口号 |
---|---|
目的端口号 | 接收方的端口号 |
序号 | 表示TCP数据流中每一个TCP段的顺序 |
确认序列 | 判断接收方有没有收到消息 |
状态位 | 表示状态 |
窗口大小 | 流量控制 |
除了做流量控制以外,TCP还会做拥塞控制,对于真正的通路堵车不堵车,它无能为力,唯一能做的就是控制自己,也即控制发送的速度
我乍一眼看流量控制与拥塞控制这俩概念不差不多嘛,然后搜了一下
3.1.3流量控制与拥塞控制的区别
流量控制(Flow Control)是指在数据发送方和接收方之间调节数据传输速率的过程,以确保接收方能够处理接收到的数据。流量控制的主要目标是防止接收方因为来不及处理过多的数据而丢失或溢出。
流量控制通常由接收方向发送方发送控制信息来实现。接收方可以使用反馈机制,例如发送确认(ACK)来告知发送方已成功接收数据,或者发送窗口大小信息来告知发送方可以继续发送的数据量。发送方根据接收方的控制信息来调整发送速率,保持在接收方可处理范围内。
拥塞控制(Congestion Control)是指在网络中防止过多的数据流入导致网络拥塞的过程。拥塞控制的主要目标是保持网络的稳定性和公平性,以避免网络资源超载、丢包和延迟增加。
拥塞控制通常由网络中的路由器、交换机和端点设备共同完成。它使用一系列的算法和机制来检测网络拥塞的迹象,并采取相应的措施来降低发送速率、减少数据流量或者重新路由数据。
拥塞控制的方法包括拥塞窗口调整、随机丢包、拥塞信号反馈等。例如,拥塞窗口调整算法(如TCP的拥塞避免算法)会根据网络拥塞的程度动态调整发送方的窗口大小,从而控制发送速率。
简而言之,流量控制是为了保护接收方免受过多数据的冲击,而拥塞控制是为了保护整个网络免受过多数据流量的冲击。流量控制主要关注点在数据接收方和发送方之间的通信,而拥塞控制主要关注点在网络的整体性能和稳定性。
需要注意的是,流量控制和拥塞控制是紧密相关的概念,它们在实际网络中相互配合以确保数据的可靠传输。流量控制的目标是为了保护接收方,同时也可以起到减轻网络拥塞的作用。而拥塞控制则是为了保护网络免受过载而进行的控制。两者共同协作可以提高网络的性能和可靠性。 请注意,流量控制和拥塞控制是网络通信中的两个重要概念,它们的目标和方法有所不同。
3.1.4TCP的三次握手
经典中的经典中的经典,通常我们用TCP的三次握手来建立请求,人话就是用TCP的三次握手来判断发送方到底和被发送方建不建立请求
我们来看这张图,客户端就是发送方,服务端就是接收方
我们之前在状态标识位syn那块说了,这是一个发起请求的标识位,发送的时候不要忘了还有序号,这里我们把发送过去的序号定义为Seq Num = client_isn一起发送给了服务端
好,服务端收到了客户端想发送请求的信息,如果服务器没有什么异常的话,他就会把syn(刚才发送请求的那个标识位)和ack(回复标识位)一并发送过来,并且ACK的值为刚才发送过去的序列号+1再发送一个序列号,这个序列号定义成了Seq Num = server_isn
这时候客户端主要就是把回复消息发送给了服务端,并且回复消息是刚才服务端发送的序号+1、
发送过去后,至此,连接就彻底建立成功了
我们来稍微简化一下这个过程
3.1.4.1三次握手的简化操作
客户端把建立连接的请求(syn)和序列号发送给服务器端
服务器端同意就把刚才的请求(syn)和回复(ack)与新的序列号发送回客户端
客户端收到后再把回复(ack)发送给服务端
TCP的三次握手重点其实很多,但这篇主要先讲基础,后面深入的部分在HTTP篇在继续讲
三次握手目的是保证双方都有发送和接收的能力
3.1.5TCP的连接状况的查看
TCP 的连接状态查看,在 Linux 可以通过 netstat -napt
命令查看。
就是这个样子的
在windows中通过在cmd输入netstat -aon | findstr "TCP"
命令查看
3.1.6TCP分割数据
在上面那个传输层中的TCP协议中我们就讲过,如果数据量太大的话,我们通过把数据分割成一段一段TCP段来实现
看一下一个比较官方一点的说法
如果 HTTP 请求消息比较长,超过了 MSS
的长度,这时 TCP 就需要把 HTTP 的数据拆解成一块块的数据发送,而不是一次性发送所有数据。
这个图的意思其实就是HTTP协议的数据的长度不要让它超过MSS,然后后面的IP协议中的最大IP报文长度是MTU
MTU
:一个网络包的最大长度,以太网中一般为1500
字节。MSS
:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。
数据会被以 MSS
的长度为单位进行拆分,拆分出来的每一块数据都会被放进单独的网络包中。也就是在每个被拆分的数据加上 TCP 头信息,然后交给 IP 模块来发送数据。
3.1.7TCP报文生成
TCP 协议里面会有两个端口,一个是浏览器监听的端口(通常是随机生成的),一个是 Web 服务器监听的端口(HTTP 默认端口号是 80
, HTTPS 默认端口号是 443
)。(这个端口是怎么来的,当我们进行HTTP操作的时候,不仅解析了域名还解析了访问数据的协议(http或者https))
在双方建立了连接后,TCP 报文中的数据部分就是存放 HTTP 头部 + 数据,组装好 TCP 报文之后,就需交给下面的网络层处理。
至此,网络包的报文如下图。
TCP报文就=TCP的包头格式+被拆分的HTTP的数据
3.2IP协议
我个人的感觉TCP协议除了建立连接以外还有把HTTP数据拆分成多个TCP段。然后IP协议是把不超过MTU个TCP段结合成IP报文
按照惯例,我们来看看IP的报文的格式
在 IP 协议里面需要有源地址 IP 和 目标地址 IP:
- 源地址IP,即是客户端输出的 IP 地址;
- 目标地址,即通过 DNS 域名解析得到的 Web 服务器 IP。
因为 HTTP 是经过 TCP 传输的,所以在 IP 包头的协议号,要填写为 06
(十六进制),表示协议为 TCP。
3.2.1源IP地址的选择
如果客户端有多个网卡,每个网卡都有一个唯一的IP地址,那么当客户端发送一个IP数据包时,需要在IP头部指定一个源IP地址。而此时,客户端应该选择哪个IP地址作为数据包的源IP地址呢?
在 Linux 操作系统,我们可以使用 route -n
命令查看当前系统的路由表。
我们看这个图,共有3条路由
这里面的意思分别是:
Destination: 目的地址,可以是主机地址、网络地址,常用的是网络地址
Gateway: 网关地址,所有未知地址都会找网关,有网关统一转发,只有边缘网络才会配置网关,并且直连网络不需要配置网关
Genmask:目的地址的子网掩码
Iface: 接口,去往目的地址的网络路径的出口(也就是从那个出口可以去往目的地址)
这里面我就先重点看Genmask与Destination
举个例子,根据上面的路由表,我们假设 Web 服务器的目标地址是 192.168.10.200
我们先用路由中掩码不为0的
我们先用第二条路由:
192.168.10.200 AND 255.255.255.0 = 192.168.10.0
与它的destination 192.168.122.0不一样
然后第三条路由:
192.168.10.0依然和第三条的destination的192.168.188.0不一样
第二条和第三条都和它不一样这时候我们再回过头来看掩码和destination = 0.0.0.0的
这表示默认网关,如果其他所有条目都无法匹配,就会自动匹配这一行。并且后续就把包发给路由器,Gateway
即是路由器的 IP 地址
3.2.2源IP地址选择的总结
在遇到有多个网卡发送的情况,我们要寻找源IP地址,需要通过Web 服务器的目标地址与网卡的掩码进行与操作获得网络号,将网络号与网卡的Destination进行对比,要是一样,就选择这个作为源IP,然后把它的Gateway作为路由器的IP地址
3.2.3IP报文生成
3.3MAC
这个MAC可不是苹果的那个MAC笔记本
通过IP协议把多个TCP段封装成多个IP报文后,我们还需要在IP报文前面添加MAC头部
在电脑上打开cmd然后输入iPconfig /all 然后查看里面的物理地址信息,这个物理地址信息就是MAC地址
一台笔记本有且只有唯一的一个MAC地址与它对应
在 MAC 包头里需要发送方 MAC 地址和接收方目标 MAC 地址,用于两点之间的传输。
一般在 TCP/IP 通信里,MAC 包头的协议类型只使用:
0800
: IP 协议0806
: ARP 协议
3.3.1MAC发送方和接收方如何确认?
发送方的MAC地址就按照刚才我说的cmd中输入iPconfig /all 然后查看里面的物理地址信息,它是在网卡生产时写入到 ROM 里的,只要将这个值读取出来写入到 MAC 头部就可以了。
但是接收方:先得搞清楚应该把包发给谁,这个只要查一下路由表就知道了。在路由表中找到相匹配的条目,然后把包发给 Gateway
列中的 IP 地址就可以了。
好,现在我们已经知道了接收方的IP地址了,怎么得出它的MAC地址
此时就需要 ARP
协议帮我们找到路由器的 MAC 地址。
ARP 协议会在以太网中以广播的形式,在以太网中找出对应的MAC地址
如果对方和自己处于同一个子网中,那么通过上面的操作就可以得到对方的 MAC 地址。然后,我们将这个 MAC 地址写入 MAC 头部,MAC 头部就完成了。在后续操作系统会把本次查询结果放到一块叫做 ARP 缓存的内存空间留着以后用,不过缓存的时间就几分钟。
也就是说,在发包时:
- 先查询 ARP 缓存,如果其中已经保存了对方的 MAC 地址,就不需要发送 ARP 查询,直接使用 ARP 缓存中的地址。
- 而当 ARP 缓存中不存在对方 MAC 地址时,则发送 ARP 广播查询。
3.3.2如何查看ARP缓存
在 Linux 系统中,我们可以使用 arp -a
命令来查看 ARP 缓存的内容。
以小林coding的来举例就是这样的
3.3.3MAC报文生成
3.4网卡
上面这个图的报文其实是一种网络包,是一种二进制的数字信息,但是我们要把它变成电信号,这样才能在网络上进行传输
负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序
所以如果你在你的电脑上看见先是网卡驱动不存在的话,那你得好好检查一下,否则你的电脑就没办法联上网了
网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。
- 起始帧分界符是一个用来表示包起始位置的标记
- 末尾的
FCS
(帧校验序列)用来检查包传输过程是否有损坏
最后网卡会将包转为电信号,通过网线发送出去。
4.交换机
我们在网卡那块才算把数据发送了出去。交换机的设计是将网络包原样转发到目的地。交换机工作在 MAC 层,也称为二层网络设备。
4.1交换机的包接收操作
其实相当于把网卡的那部分反过来走一遍
首先,电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。
然后通过包末尾的 FCS
校验错误,如果没问题则放到缓冲区。这部分操作基本和计算机的网卡相同,但交换机的工作方式和网卡不同。
计算机的网卡本身具有 MAC 地址,并通过核对收到的包的接收方 MAC 地址判断是不是发给自己的,如果不是发给自己的则丢弃;相对地,交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。因此,和网卡不同,交换机的端口不具有 MAC 地址。
这就和TCP和UDP很像,TCP会确认你有没有接收到该消息,但是UDP不会管这个
将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。
MAC表地址主要放了两个东西
- 一个是设备的MAC地址
- 一个是该设备连接在交换机的哪个端口上
MAC地址和这个端口就像HashMap一样,呈现出映射关系
交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口。
好,我们现在发现问题了,我们能将信号发送到相应的端口上考的就是这个包的接收方的MAC是存在在MAC地址表上的,那么如果不存在呢?
4.2包的接收方不存在MAC地址表上
这可能是因为具有该地址的设备还没有向交换机发送过包,或者这个设备一段时间没有工作导致地址被从地址表中删除了。
这种情况下,交换机无法判断应该把包转发到哪个端口,只能将包转发到除了源端口之外的所有端口上,无论该设备连接在哪个端口上都能收到这个包。
这样做不会产生什么问题,因为以太网的设计本来就是将包发送到整个网络的,然后只有相应的接收者才接收包,而其他设备则会忽略这个包。
发送了包之后目标设备会作出响应,只要返回了响应包,交换机就可以将它的地址写入 MAC 地址表,下次也就不需要把包发到所有端口了。
如果接收方 MAC 地址是一个广播地址,那么交换机会将包发送到除源端口之外的所有端口。
以下两个属于广播地址:
- MAC 地址中的
FF:FF:FF:FF:FF:FF
- IP 地址中的
255.255.255.255
5.路由器
网络包经过交换机之后,现在到达了路由器,并在此被转发到下一个路由器或目标设备。
这一步转发的工作原理和交换机类似,也是通过查表判断包转发的目标。
不过在具体的操作过程上,路由器和交换机是有区别的。
- 因为路由器是基于 IP 设计的,俗称三层网络设备,路由器的各个端口都具有 MAC 地址和 IP 地址;
- 而交换机是基于以太网设计的,俗称二层网络设备,交换机的端口不具有 MAC 地址。
5.1路由器基本原理
路由器的端口具有 MAC 地址,因此它就能够成为以太网的发送方和接收方;同时还具有 IP 地址,从这个意义上来说,它和计算机的网卡是一样的。
当转发包时,首先路由器端口会接收发给自己的以太网包,然后路由表查询转发目标,再由相应的端口作为发送方将以太网包发送出去。
5.2路由器的包接收操作
首先,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的 FCS
进行错误校验。
如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。
这一步和网卡的操作很像
完成包接收操作之后,路由器就会去掉包开头的 MAC 头部。
MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃。
接下来,路由器会根据 MAC 头部后方的 IP
头部中的内容进行包的转发操作。
转发操作分为几个阶段,首先是查询路由表判断转发目标。
具体的工作流程根据上图,举个例子。
假设地址为 10.10.1.101
的计算机要向地址为 192.168.1.100
的服务器发送一个包,这个包先到达图中的路由器。
判断转发目标的第一步,就是根据包的接收方 IP 地址查询路由表中的目标地址栏,以找到相匹配的记录。
路由匹配和前面讲的一样,每个条目的子网掩码和 192.168.1.100
IP 做 & 与运算后,得到的结果与对应条目的目标地址进行匹配,如果匹配就会作为候选转发目标,如果不匹配就继续与下个条目进行路由匹配。
如第二条目的子网掩码 255.255.255.0
与 192.168.1.100
IP 做 & 与运算后,得到结果是 192.168.1.0
,这与第二条目的目标地址 192.168.1.0
匹配,该第二条目记录就会被作为转发目标。
实在找不到匹配路由时,就会选择默认路由,路由表中子网掩码为 0.0.0.0
的记录表示「默认路由」。
5.3路由器的发送操作
接下来就会进入包的发送操作。
首先,我们需要根据路由表的网关列判断对方的地址。
- 如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,还未抵达终点,还需继续需要路由器转发。
- 如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,也是就终于找到 IP 包头里的目标地址了,说明已抵达终点。
知道对方的 IP 地址之后,接下来需要通过 ARP
协议根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址。
路由器也有 ARP 缓存,因此首先会在 ARP 缓存中查询,如果找不到则发送 ARP 查询请求。
接下来是发送方 MAC 地址字段,这里填写输出端口的 MAC 地址。还有一个以太类型字段,填写 0800
(十六进制)表示 IP 协议。
网络包完成后,接下来会将其转换成电信号并通过端口发送出去。这一步的工作过程和计算机也是相同的。
发送出去的网络包会通过交换机到达下一个路由器。由于接收方 MAC 地址就是下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器。
接下来,下一个路由器会将包转发给再下一个路由器,经过层层转发之后,网络包就到达了最终的目的地。
不知你发现了没有,在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。
6.问题
我看完之后其实MAC及它之前的还好,到网卡,交换机,路由器就有点蒙蔽了,所以重新整理一下
首先是网卡,网卡的主要作用是把我们的数字信号转化为电信号。网卡是计算机的一种硬件设备,用于将计算机与网络相连接。它负责将计算机内部的数据包封装成网络数据包,并将其发送到网络上。网卡同时也负责接收网络数据包,并将其解封装成计算机内部的数据包。网卡一般由网络接口控制器和物理接口两部分组成。
路由器,首先有一点我要说明,无论是网卡还是交换机,它们都只能把网络数据包发送到局域网,如果你想把数据包发送到其他的地方比如说:其他局域网或者广域网上,就需要通过路由器等设备来实现。
我一时间没有发现网卡和交换机的区别,然后搜了一下,它的解释如下:
网卡是计算机和网络之间的接口,负责将计算机内部的数据包转换成网络数据包,并将其发送到局域网;而交换机是局域网内数据包的转发设备,用于将数据包转发到目标设备,实现局域网内的通信。交换机并不会再把数据包发送到局域网而是局域网中的设备上
Comments | NOTHING