有的软件返回主界面就退出了温馨提示 出来就返回不了怎么回事?

2.1 UDPUDP 的数据报文格式:由 UDP 报头、UDP 数据载荷(完整的应用层数据)组成。把应用层数据报分装成 UDP 数据报,本质上就是在应用层数据包的基础上,添加了 8 个字节的报头。目的端口:即为 服务器端口。
源端口:即为 操作系统给客户端自动分配的端口。端口号会被打包到 UDP 数据报中。
报文长度是 2 个字节,0-64k 在现代互联网当中,就可能不够用了。数据大的话,就会进行拆包,然后分为多个发送,接收方再重新拼接起来,但是可能回出现丢包和乱序,所以就改成 TCP 来解决,因为 TCP 没有大小限制。
校验和就是用来验证网络传输的这个数据是否正确。因为网络传递的本质就是:光信号和电信号,但是外界的磁场之类的会影响到结果。可能就会导致 0 变成 1,就导致数据出错了,所以校验和就能帮助我们发现数据中的错误。还可以使用数据内容参与运算,如果是基于数据内容得到的校验和,那么数据出错的话,被识别出来的概率还是很高的。这里的 校验和 与 以太网 的校验和一样。
2.2 TCPTCP,即 Transmission Control Protocol,传输控制协议。就是对数据的传输进行一个详细的控制。 TCP 协议段格式源/目的端口号:表示数据是从哪个进程来,到哪个进程去。
32 位序号/32 位确认序号:后续补充
4 位首部长度:4 位就是 4 个 bit 位的意思(取值范围 0~15),来表示 TCP 报头的长度。
注意:有 4 位,只能表示 0~15,因此这里的单位是 4 字节。例如,4 位 bit 数:1111,此时的报头长度为:15 * 4 = 60 字节。即为,4 位 bit 数转化成 10 进制数,再乘以 4,得出的结果就是报头的长度。不同于 UDP,TCP 的报头的变长的,不像 UDP 是固定的 8 字节。原因:在于 TCP 协议段格式中 “选项” 一栏。因为这个选项,可有可无,可有一个或者多个,因此TCP的报头不是固定的长度。
保留位:现在不用,但是不能保证后面不会用到。为了未来升级,留有空间。
比如 UDP,把报文长度的 2 字节改成 4 字节,不好意思,改不了。除非把全世界的 UDP 都改了,但明显不现实。因此我们想升级一个协议是一件相当麻烦的事情。当对于推翻之前的格式,不如在设计协议之初,留有一点可扩展的空间。
6 位标志位:
URG:紧急指针是否有效。
ACK:确认号是否有效。
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走。
RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段。
SYN:请求建立连接;我们把携带SYN标识的称为同步报文段。
FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段。
16 位窗口大小:后续补充
16 位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不 光包含TCP首部,也包含TCP数据部分。
16位紧急指针:标识哪部分数据是紧急数据。
40字节头部选项:暂时忽略。
可靠传输可靠传输是 TCP 的核心机制。引入 TCP 的关键原因,就是为了保证可靠传输。实现可靠传输的核心:确认应答
超时重传
确认应答机制(可靠性)确认应答就是发出去之后,对方收到了。但是消息可能会乱序。
避免出现乱序,就可以根据编号机制来解决,根据编号就可以知道消息是第几条了。
就是根据编号来确定当前的 应答报文 就是针对哪个消息进行的确认应答。
就像下面这样:A 给 B 发送了 1000 个字节,序号是 1 - 1000。B 给 A 返回的应答报文(ACK)就会带有一个确认序号,为 1001(这个 1001 代表的是 小于 1001 的数据已经被 B 收到了,接下来 A 应该从 1001 这个序号开始往后进行传递)确认应答的作用:来确认接收端收到数据了。
可以知道收到的是哪一条数据。
超时重传机制(可靠性)主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B;
如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发;
但是,主机A未收到B发来的确认应答,也可能是因为ACK丢失了;如果是 ACK 丢了,虽然对方收到了消息,但是我收不到 ACK(ACK 丢了),发送方超出了等待时间,就会重新发送一次。那么就会导致接收方收到了重复的消息:TCP 内部会有一个去重操作,接收方收到的数据会先放在操作系统的 接收缓冲区 当中的。
收到新的数据,TCP 就会去 接收缓冲区(一段内存,每个 socket 都有,按照序号来进行去重) 当中检查有没有这个消息,如果有,就丢弃,没有的话,就放到缓冲区。用来保证程序调用 socket API 拿到的这个数据一定是不可重复的。
重传如果失败,还会继续尝试,也不会无休止的重传,连续几次失败的话,就认为是网络遇到了严重的情况,再怎么重传也可能不行,就只能放弃(自动断开与 TCP 的连接)。重传的时间间隔会逐渐变大。如何确定超时的时间?
最理想的情况下,找到一个最小的时间,保证 "确认应答一定能在这个时间内返回"。
但是这个时间的长短,随着网络环境的不同,是有差异的。
如果超时时间设的太长,会影响整体的重传效率。
如果超时时间设的太短,有可能会频繁发送重复的包。
TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。
Linux中(BSD Unix和Windows也是如此),超时以500ms为一个单位进行控制,每次判定 超时重发的超时时间都是500ms的整数倍。
如果重发一次之后,仍然得不到应答,等待 2*500ms 后再进行重传。
如果仍然得不到应答,等待 4*500ms 进行重传。依次类推,以指数形式递增。
累计到一定的重传次数,TCP认为网络或者对端主机出现异常,强制关闭连接。
连接管理机制(可靠性)连接管理也是 TCP 保证可靠性的一个机制,主要是两部分:如何建立连接。
如何断开连接。
如何建立连接(三次握手)客户端和服务器之间,通过三次交互(三次握手),完成了建立连接的过程。三次握手只是一个形象化的比喻:其实一次握手,就是一次交互的过程。就是客户端 给 服务器 发了一个数据,这就相当于一次握手。
服务器再给客户端反馈一个数据,这就是另外一次握手。
客户端 根据服务器的反馈,而进行反馈,告诉服务器,它接受到了它的反馈。
一共经历3次,就完成这个三次握手。简化流程图如下:第一次握手的时候客户端给服务器发一个 SYN 同步报文段。意思就是客户端要和服务器建立连接。当** SYN 为 1** 时,表示当前报文为一个 **同步报文段。**即为 主机 A 与 主机 B 之间要建立连接。客户端 先给 服务器 发起一个 SYN 同步请求:
当服务器收到这个请求时,就会立即做出回应(ACK),表示我收到了你的SYN。服务端发送 ACK 的同时,也要发送一个 SYN,表示服务器想和客户端建立连接:
(此处服务器的 ACK和SYN 可以合并到一起)客户端收到服务器的 SYN 之后,也会立即返回一个 ACK:
这样的话,双方各自向对方发送 SYN,再各自向对方发送 ACK,双向奔赴之后就建立连接了。如果 ACK 这一位为 1,就表示这个报文是一个确认报文段(确认应答报文也就是 ACK 为 1)。ACK 这一位为 1 的时候,起到一个应答效果,用来确认消息是已经送到了的。注意:每次要传输的数据,都要结果一系列的封装和分用,才能完成传输。如果 服务器 的 SYN 和 ACK 分开发送的话,就会导致封装的次数变多,导致效率变低。只要把六个标志位中的 ACK 和 SYN 变为 1。就可以封装在一起了。封装在一起后的样子:即为 三次握手。常见的状态:LISTEN:表示服务器启动成功,端口绑定成功,随时可以有客户端来建立连接。就像是手机开机,有信号,可以随时接电话。
ESTABLISHED:表示当前客户端已经连接成功,随时可以进行通信。类似有人给我打电话,已经接通了,可以进行交流了。
如何断开连接(四次挥手)三次握手,就让客户端和服务器之间建立好了连接。其实在建立好连接之后,操作系统内核当中,就需要使用一定的数据结构来保存连接的相关的信息,保存的信息其实最重要的就是前面说的五元组:源IP、源端口、目的IP、目的端口、TCP。有一天,连接断开了,那么五元组保存的连接信息就没意义了,对应的空间就可以释放了。四次挥手,就是和对方断开连接:就是双方各自向对方发送了 FIN(结束报文段)请求,并且各自给对方一个 ACK 确认报文。这样的话,就完成了四次挥手。四次挥手就是各自和对方说断开连接。四次挥手中重要的状态:CLOSE_WAIT:
四次挥手挥了两次之后出现的状态,这个状态就是在等待代码中调用 socket.close()方法,来进行后续的挥手过程。
正常情况下,一个服务器上面不应该存在大量的 CLOSE_WAIT 如果存在,说明大概率是代码 bug,close 没有被执行到。
TIME_WAIT:
谁主动发起 FIN(先断开连接的一方),谁就进入 TIME_WAIT。
起到的效果:就是给最后一次 ACK 提供重传机会,表面上看起来 A 发送完 ACK 之后,就没有 A 的啥事了。
按理说 A 就应该销毁链接,释放资源了,但是并没有直接释放,而是会进入 TIME_WAIT 状态等待一段时间,一段时间后,再来释放资源。等这一会儿,就是怕最后一个 ACK 丢包了,如果丢包了,就意味着 B 过一会儿就会重传 FIN。
如果最后一个 ACK 丢了,B 就无法区别是 FIN 丢了,还是 ACK 丢了。于是 B 就假设 FIN 丢了,就重传 FIN(超时重传)。因为如果断开的太早,就没办法继续重传了。
TIME_WAIT 持续时间:2*MSL。MSL:表示网络上任意两点之间,传输需要的最大时间。这个时间也是系统上可以配置的参数,一个典型的设置就是:60s(随便想的时间)。
滑动窗口(效率)滑动窗口存在的意义是,保证可靠性的前提下,尽量提高传输效率。以下是不使用滑动窗口的传输机制:从图里就可以看到,由于确认应答机制存在,就导致了当前每次执行一次发送数据,都需要等待上一个 ACK 到达,大量的时间都浪费在等待 ACK 上面了,就导致效率变低了。使用滑动窗口就是一次发送一堆数据:就相当于是一次发了 4 组数据,在发生这 4 组数据的过程中,不进行等待,这四组都发完了再统一等。
即为,把等待多份 ACK 的时间压缩成等待一份 ACK 了。
窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是4000 个字节(四个段)。
发送前四个段的时候,不需要等待任何ACK,直接发送。
收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推。
操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有 应答;只有确认应答过的数据,才能从缓冲区删掉。
窗口越大,则网络的吞吐率就越高。
当 ACK(2001)到达之后,就认为 1001 - 2000 的数据已经收到了,接着就可以发送下一组的数据 2001 - 3000,等待的 4 组ACK发生了变化:3001,4001,5001,6001。滑动窗口的窗口越大,就可以认为传输速度越快,窗口大了,同一份时间内等待的 ACK 就更多。总的等待 ACK 的时间就少了。丢包那么如果出现了丢包,如何进行重传?这里分两种情况讨论。情况一:数据包已经抵达,ACK 被弄丢了。在发送 4001 的数据之前,发现收到了一个 2001 的 ACK,1001 并没有收到.
这里的 1001 已经不重要了。因为 2001 的意思就是:2001 之前的数据全都已经确认收到了。
由于 ACK 确认序号的含义,就保证了后一条 ACK 就能涵盖前一条。
确认序号的含义:表示当前序号之前的数据全都收到了。
就像发送方收到了 5001,就意味着 1-5000 的数据都确认收到了,3001、4001 被丢包也毫不影响。只要收到了 5001,就涵盖了 3001、4001 表达的信息。
情况二:数据包丢了。由于 1001-2000 这个数据丢了,所以 B 就再反复索要 1001 这个数据。即使 A 给 B 已经发后面的数据了,这个时候 B 仍然再索要 1001 这个数据。当 A 被 B 索要多次之后,A 就明白了这个数据丢了,就会触发重传。当 B 收到这个数据的时候,返回的 ACK 直接就是 7001 了。在重传 1001 - 2000 的数据之前,接收缓冲区如下:重传之后就是把缺口补上了,后面那些数据已经传过了,就不用再重传了,然后 B 就向 A 索要从 7001 开始的内容就好了:快速重传就像是看直播的时候有事忙,等忙完的时候把拉下的一部分再补起来就好了。流量控制(可靠性)流量控制是对滑动窗口的进一步补充,本质上就是在控制滑动窗口的大小,目的也是为了可靠性。滑动窗口越大,传输速率越高,不光要考虑发送方,还得考虑接收方。
发送方发的太快,接收方处理不过来,就会把新收的包给丢了,发送方还得重传。
流量控制的关键是能够衡量接收方的速度,直接使用接收方接受缓冲区的剩余空间大小,来衡量当前的处理能力。
可以把接收缓冲区理解为一个阻塞队列。B 的应用程序,在调用 read 方法的时候,就是从接收缓冲区中来取数据。通过 ACK 报文来看缓冲区大小,如果接收方反馈的窗口大小是 0,那么发送方也会发一个信息,用来探测有没有空间。
就像下面的图片,类似于一个生产者消费者模型:主机 A 发送的数据到达了主机 B 的接收缓冲区,此时主机 A 就是生产者。主机 B 的应用程序,通过 socket api 来读取数据,被 socket api 读到的数据就从缓冲区中删掉了,应用程序就是消费者。接收缓冲区就是交易场所(类似与一个队列)所说的窗口大小,是指发送方(主机 A)批量发送多少数据。比如,主机 A 发送的数据很快,窗口很大,此时接收缓冲区的数据也会增长很快。如果主机 B 的应用程序读取数据读的不快,随着时间的推移,接收缓冲区逐渐就满了。如果不做任何限制,主机 A 还是按照往常速度发,此时新来的数据就没有地方保存了,就被内核丢弃了。这个过程就像是一个水池一样:水位高了(剩余空间小了),进水就要慢点。水位低了(剩余空间大了),进水就要快点。探测接收缓冲区剩余大小的具体流程:首先 A 给 B 发送 1 - 1000 数据的时候,B 返回数据的时候会返回接收缓冲区还剩 3000(就是 B 主机 1001 ACK 的右边的 3000) 的空间,那么下一次 A 就可以一次发送 3000 数据了。当 B 收到 3000 数据的时候,剩余缓冲区的大小就是 0 了。不过要注意的是: 当接受缓冲区大小为 0 的时候,A 也会继续发送窗口探测数据,当探测到接受缓冲区剩余大小又可以发送数据的时候,就可以继续发送数据了。窗口大小(接收区的剩余空间)是如何返回给发送方的呢?在前面提到的 TCP 协议段中,有 16 位窗口大小来表示当前剩余的空间,当收到 ACK 时,就能知道当前窗口剩余空间的大小了。那么问题来了,16位数字最大表示65535,那么TCP窗口最大就是65535字节么? 实际上,TCP首部40字节选项中还包含了一个窗口扩大因子M,实际窗口大小是 窗口字段的值左移 M位。拥塞控制(可靠性)拥塞控制也是滑动窗口的延申,也是限制滑动窗口的发送速率。控制衡量的是:发送方到接收方 整个链路之间的拥堵情况,都会影响传输速率。
开始的时候,以一个比较小的窗口来发送数据,如果数据很流畅的到达了,那么就加大窗口大小。
加大到一定程度之后,出现了丢包(就意味着链路出现拥堵了),然后再减小窗口。
通过反复的 增大/减小 最终达到”动态平衡“。通过拥塞窗口来限制滑动窗口的大小。
最终滑动窗口的大小 由 拥塞窗口 和 流量控制窗口共同决定,由小的一方决定。一旦丢包,就立刻让窗口变小,降低速度,然后继续去试探的增大。
如果把窗口一下变得很小,就是期望这次传输,一定能成功。
下面的图就描述了拥塞控制中,窗口大小的变化规则:x 轴上的 传输轮次 就是第几次传输数据。
一开始指数增长是因为,初始窗口太小,而我们实际上可能触发丢包的值很大。因此,指数增长可以帮我们快速找到丢包的界限。
但是增长到一定的程度时,就会进入线性增长。因为即将达到丢包的界限,如果再来指数增长,就可能一次越界,直接触发丢包。如下图:当线性增长达到丢包的界限,发生丢包之后,就让拥塞窗口立即变小,回归到初始窗口的大小。一次变得很小之后,也就是希望这次传输一定能成功。如下图:延时应答(效率)如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小。假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答,返回的窗口就是500K。
但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了。
在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来。
如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是 1M。
捎带应答(效率)在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是 "一发一收" 的。意味着客 户端给服务器说了 "How are you",服务器也会给客户端回一个 "Fine, thank you";那么这个时候ACK就可以搭顺风车,和服务器回应的 "Fine,thank you" 一起回给客户端。面向字节流(粘包问题)面向字节流会引起:粘包问题。指的是在应用层数据报,在 TCP 缓冲区中,若干个应用层数据报混在一起了,分不出来谁是谁。如下图:如何解决粘包问题呢?通过设计一个合理的应用层协议来解决,核心就要明确应用层数据中,包和包之间的边界,以下有两种方式:给应用层数据设定 “结束符” 或者 “分隔符”。
举例:以 分号 为结束符:给应用层数据设定 “长度”。
举例:约定每个应用层数据报的前 4 个字节,存储数据报的长度:TCP 异常情况进程终止触发关闭文件的操作,正常的关闭。如,任务管理器里面的结束任务:不管进程是怎么终止的,本质上都会释放对应的 PCB,也会释放对应的文件描述符,一样会触发 四次挥手。“进程终止” 不代表连接就终止,进程终止其实是相当于调用了 socket.close()而已。 机器重启机器重启的时候,其实也是先杀进程,仍然进行四次挥手。 机器掉电/网线断开这个是突发的情况,机器是来不及进行任何动作的!
掉电的是接收方,此时另一边还在发送数据,此时显然发送方不会再有 ACK 了,于是就会超时重传。重传几次之后,就会尝试重置连接,复位报文段:,再然后发送方就会放弃这个连接,把连接对应的资源就回收了。
掉电的是发送方,此时另一方在尝试接收数据,此时却接收不到任何数据。接收方如何知道,发送方是挂了?还是发送方暂时还没发呢?此时接收方采取的策略,就是 “心跳包”机制:
每隔一段时间,向对方发送一个 PING 包,期待对方返回一个 PONG 包,如果 PING 包发过去,过了很久还没有收到 PONG 包,并且重试几次都不行,此时就认为对方已经挂了。
2.3 TCP 与 UDP 的对比对可靠性有一定的要求,就使用 TCP。
如果传输的单个数据报比较长(超过 64 k),使用 TCP。
对可靠性要求不高,对于效率要求更高,使用 UDP。
如果需要广播,优先考虑 UDP。
广播:一份数据同时发送给多个主机。
UDP 自身就支持广播,但是 TCP 自身不支持,就只能在应用层程序中,通过多个连接,轮询的方式给每个主机发送数据(伪广播)。
2.4 经典面试题:基于 UDP 如何实现可靠传输那就根据 TCP 怎么实现的,UDP 的在传输层也照着实现一遍就好。本质就是在应用层基于 UDP 复刻 TCP 的机制。
实现确认应答机制,把每个数据接收到之后,都要反馈一个 ACK (这就不是内核返回的了,而是应用程序自己定义一个 ACK 包,发送回去)。
实现序号/确认序号,以及实现去重。
实现超时重传。
实现连接管理。
要想提高效率,实现滑动窗口。
为了限制滑动窗口,实现流量控制/拥塞控制。
实现延时应答、捎带应答、心跳机制....
3.1 IP 协议报头结构IP 协议报头结构和作用:
**4 位版本:**IP 协议的版本号,当前只有两个取值:4 和 6,对于 IPV4 来说,就是 4。
**4 位首部长度:**IP 的报头和 TCP 类似,都是可变的,带有选项。
4 bit的取值范围为 0 - 15,这里的单位也是 4 字节。如果取值 1111 => 15,实际表示的首部长度为 15 * 4 = 60 字节。
8位服务类型TOS:3位优先权字段(已经弃用),4位TOS字段,和1位保留字段(必须置为0)。4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。 这四者相互冲突,只能选择一个。
所以 IP 协议就可以通过 TOS 来切换形态:
最小延时:从主机 A 到主机 B 之间,取一条时间最短的路径。
最大吞吐量:从主机 A 到主机 B 之间,取一条路径,它的传输带宽是最高的。
最高可靠性:从主机 A 到主机 B 之间,取一条最不容易丢包的路径。
最小成本:从主机 A 到主机 B 之间,取一条开销最小的路径。
此时,我们就可以根据实际需要,来选择一条合适的路径。
16 位总长度:16 位 => 最大长度 64k,因此,单个 IP 数据报最大长度是不能超过 64k。如果要构造一个更长的数据报(比如载荷部分已经超过 64k了,咋办?IP协议自身实现了分包和组包这样的操作)
这三个字段就是用来 分包和组包 的。
16 位标识(id):相当于 IP 数据报的身份标识。把一个数据拆成多个 IP 数据报的时候,这三个 IP 数据报的标识是一样的。
3 位标志:第一位保留(保留的意思是现在不用,但是还没想好说不定以后要用到)。 第二位置为1表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文。第三位表示"更多分片",如果分片了的话,最后一个分片置为1,其他是0。类似于一个结束标记。
13 位片偏移:是分片相对于原始IP报文开始处的偏移。其实就是 在表示当前分片在原报文中处在哪个位置。就相当于描述了当前这个包的顺序。
举例:假设我们有一个很长的 IP 数据报:如果整个 IP 数据报太长了,IP 协议就会把这个大包拆成多个小包,保证每个包都不超过 64k。假设分成两个小包,每个小包是一个 IP 数据报,即每个小包都有一个 IP 报头。除了 IP 报头外,将剩余数据分成两个部分:,小包大小不超过 64k。注意:对于 IP 数据包来说,根本不关心数据载荷里是什么,只是单纯的对数据进行切分。
如何区分多个 IP 包,是从同一个数据拆分出来的呢?
根据 16 位标识,被拆解成多个 IP 数据报的 16 位标识的值都是一样的。,通过 IP 协议里面的标识,看到标识相同的,就可以知道哪些包是来自同一份数据。组包的时候,按照什么顺序进行组合,才能保证组合出来的数据是合格的?
通过 13 位片位移,来描述多个包的相对顺序。片位移的值越小,说明这个包所在的位置越靠前。由于网络的复杂性,接收方接收的顺序可能跟发送方发送的顺序不一样,所以通过片位移,就能确认正确的组包顺序。如何确定接收到的小包是不是最后一个小包?
通过 3 位标志位,只有 第 3 位能用,当这一位标志为 0 时,表示 后续还有小包。当这一位标志为 1 时,表示 当前是最后一个包。
:::
8 位生存时间(TTL):表示一个 IP 数据报,在网络上还能存在多久,这里的单位不是 s 或者 ms,而是转发次数。IP 数据报被发送的时候,会有一个初始的TTL(如常见的取值:128或64),IP 数据报每次经过一个路由器,TTL就会 -1。如果 TTL 耗尽,减到 0 时,收到这个包的路由器就会把这个包给丢弃。
这样的机制,主要是因为有些包里面的 IP 地址,可能永远也到不了(如,翻墙,IP 地址不存在等),像这种包,不可能在网络上无休止的转发(这样会占用大量的硬件资源)。正常情况下,IP 数据报都会在既定的 TTL 内到达目的 IP。
源 IP 地址:发送方主机地址。
目的 IP 地址:接收方主机地址。
3.2 IP 协议核心功能地址管理:通过一系列的规则,把网络上的设备的地址给描述出来。
路由选择:根据当下的源地址和目的地址,规划出一条合适的路径。
地址管理IP 地址是一个 点分十进制 构成的数据。对于 IP 地址来说,里面还可以进一步进行划分。可以把 IP 地址分成下面两个部分:在 cmd 中输入 ipconfig 可以查看 IP 配置:我们要求:同一个局域网里,不同主机之间的网络号是相同的,主机号不能相同。两个相邻的局域网(同一个路由器连接的)也是不同的。那么,到底前多少个 bit 位是网络号,其实是不固定的。通过引入 “子网掩码” 这样的概念来表示多少个 bit 位是网络号。子网掩码:也是一个 32 位,点分十进制来表示的整数。
子网掩码的左侧都是 1,右侧都是 0(不会 1 0 混着排列)
左边的这些 1 就表示哪些位是网络号,剩下的 0 就表示哪些位是 主机号。
像下面这样:计算当前网络的网络号:一般家用的场景中,一个局域网设备很少(不会超过 255 个),常见的子网掩码就是 255.255.255.0,如果一个局域网设备多了,子网掩码就会出现一些其他值。
拓展:一些特殊的 IP 地址
如果 IP 的主机号为 全0,该 IP 就表示网络号(局域网里的一个正常的设备,主机号是不能设为0的)
如果 IP 的主机号 全1(255),该 IP 就表示 “广播地址”,即:往这个广播地址上发送的信息,整个局域网中的设备都能收到。
如果 IP 地址是 127 开通的,该 IP 都表示 “环回 IP”,也就是主机自己的 IP。典型 IP 代表:127.0.0.1
10 开头、192.168 开头、172.16 至 172.31 开头,如果 IP 地址是这三种开头的,就表示该 IP 地址是一个局域网内部的 IP 地址(内网IP)
除了上述 4 种 IP 地址,剩下的 IP 地址成为 外网IP(直接在广域网上使用的IP)
要求:外网 IP 地址,一定要唯一。每个外网 IP 都会对应到唯一的一个设备。而内网 IP,只是在当前的局域网中是唯一的,即:不同局域网中,可以有相同的内网 IP 设备。
IP 地址不够用不同的局域网里,有相同的 IP 设备,主要就是因为当前的 IPv4 协议,使用的地址是 32 位的整数。32 位整数表示的数据范围,就是 42亿9千万。如果给每个设备都分配一个唯一的 IP 地址,就意味着世界上的设备不能超过这么多。所以就有了这样的方式。解决 IP 地址不够用:
动态分配 IP 地址:每个设备连上网的时候,才有 IP,不联网的时候就没 IP(这个IP就给别人用),通过 动态IP 来解决 IP地址不够用的问题。
NAT 机制:就是让多个设备共用一个 IP(外网IP)把网络分为 内网 和 外网。内网可以共用一个 外网的IP。也就是这里的外网 IP,会给所有接入这个运营商设备的局域网都来使用这个 外网IP。外网区分内网的数据,就是通过端口号来区分的。网络的连接,是一个 五元组,即使是 IP 相同也没事。有 NAT 机制,就会隐含一个重要的结论:
对于一个 外网IP 来说,可以在互联网的任意位置都能访问到。
对于一个 内网IP 来说,只能在当前局域网内部访问,就是 局域网1 的设备,不能使用内网访问 局域网2 的设备。
内网IP 是可以重复的,只有在局域网内才是唯一的。
不同的局域网访问的话,就需要一个带有 外网IP 的机器,然后 局域网1 把数据放到 外网服务器,然后 局域网2 就可以访问到外网服务器,就会修改 IP数据报,把内网发出的 源IP,改为 外网IP。
NAT 也是存在极限的,端口号个数是 65535,如果一个局域网内的连接数超过了 65535,这时候 NAT 就不一定好使了,因为端口号不够用了。NAT 相当于是续命了,并不是从根本解决。
IPv6:从根本解决了 IP 地址不够用的问题。因为 IPV6 在报头中使用了更长的字段来表示 IP地址,使用 16 个字节来表示。16个字节,128位,之前是 4个字节,32位。IPv6 比 IPv4 能表示的多很多很多。IPv6 地址如下:
每个数字都是一个十六进制的数字(4 bit),每个冒号分割了 2 个字节。
IPv6 使用率不是很高的原因是:支持 IPV4 和 IPV6 需要两截然不同的机制。现有的大量网络设备(路由器…)很可能只支持 IPV4,不支持 IPV6。IP地址的划分,是通过 子网掩码 划分的,在子网掩码之前,是通过 ”分类” 的方式来划分的,把 IP 地址分成了 ABCDE。这五类,每一类分别都有几位是 网络号,几位是 主机号。
路由选择

我要回帖

更多关于 软件返回主界面就退出了 的文章