java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起

PART1:计算机网络体系可以大致分为一下三种,

  • 每一层有自己对应的协议,每一层都是向上一层提供服务,每个分层中所有的协议都称为协议栈
    • 协议:网络中传输信息时的规范和规则
      java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第1张图片
      java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第2张图片
      java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第3张图片
      • 各层一些重要的协议
    • 网络:通过网线、卫星等传输介质把分布在不同地理位置【跨地域】的主机(鸡蛋们)连接起来,通过网络协议(的约束或者规范)实现主机之间的数据传输和资源共享的目的
  • OSI七层模型:大而全,但是比较复杂、而且是先有了理论模型,没有实际应用【为了使得多种设备能通过网络相互通信,和为了解决各种不同设备在网络互联中的兼容性问题,国际标准化组织制定了开放式系统互联通信参考模型
    • 七层网络体系结构各层的主要功能::
      • 应用层:(我们能接触到的就是应用层了,手机,电脑这些这些设备都属于应用层。)为应用程序提供交互服务。在互联网中的应用层协议很多,如域名系统DNS,支持万维网应用的HTTP协议,支持电子邮件的SMTP协议等。(应用层协议基本上不是基于TCP就是基于UDP的,因为要靠这俩哥们向上层提供服务呀)
        java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第4张图片
        • 应用层是不用去关心数据是如何传输的。应用层主要提供两个终端设备上的应用程序之间信息交换的服务,它定义了信息交换的格式,消息会交给下一层传输层来传输。 我们把应用层交互的数据单元称为报文
          • 应用层协议定义了网络通信规则,对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如支持 Web 应用的 HTTP 协议,支持电子邮件的 SMTP 协议等等。
        • 应用层是工作在操作系统中的用户态,传输层及以下几层则工作在内核态
          应用层中的各个应用程序(浏览器)委托收发数据的过程的关键点就是像对DNS服务器发送查询一样,调用Socket库中的特定程序组件(也就是OS那些方法们,API)。访问DNS服务器时我们调用的是一个叫作gethostbyname的程序组件(也就是解析器),而这一次则需要按照一定的顺序调用若干个程序组件,其过程如下图所示。下面咱们以HTTP工作过程包含下面五个方面为例:
          java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第5张图片
        • HTTP工作过程包含下面四个方面:咱们心里得明白,你应用层的HTTP或者其他协议再牛,你最后还得通过传输层去进行下一步工作,像下面这样。但是不管是在下面哪一个阶段,Socket库中的程序组件(也就是一堆API或者说OS的方法们)都会被调用来执行相关的收据收发操作。浏览器等应用程序不会自己去创建套接字、连接管道、放入数据等这些工作,而是委托OS的协议栈来代劳。
          java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第6张图片
          下面这四步就是HTTP的工作过程。HTTP协议将HTML文档和图片都作为单独的对象来处理,每获取次数据,就要执行一次连接、发送请求消息、接收响应消息、断开的过程
          java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第7张图片
          因此,如果一个网页中包含很多张图片,就必须重复进行很多次连接、收发数据、断开的操作。对于同一台服务器来说,重复连接和断开显然是效率很低的,因此后来人们又设计出了能够在一 次连接中收发多个请求和响应的方法。在HTTP版本1.1中就可以使用这种方法,在这种情况下,当所有数据都请求完成后,浏览器会主动触发断开连接的操作。浏览器与Web服务器之间收发消息的过程中实际负贵收发消息的是协议栈、网卡驱动和网卡,只有这3者相互配合,数据才能够在网络中流动起来
          • (1):创建套接字阶段(调用socket后socket套接字就创建好了):这条管道不是一开始就有,而是在进行收发数据操作之前先建立起这条管道才行(最重要的是建立管道两端的数据出入口,这些出入口就是套接字。相当于我们需要先创建套接字然后将套接字连接起来形成管道),然后等待客户端向该套接字连接管道。当服务器进入等待状态时客户端就可以连接管道了
            • 创建套接字时,首先由OS的内存模块分配一个套接字所需的内存空间,然后向其中写入初始状态。
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第8张图片
              在这个过程中,协议栈首先会分配用于存放一个套接字所需的内存空间。用于记录套接字控制信息的内存空间并不是一开始就存在的,因此我们先要开辟出这样一块空间来,这相当于为控制信息准备一个容器。

              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第9张图片
            • 实际上服务器在准备接受客户端的握手请求之前,需要先 listen 一下,需要准备半连接队列和全连接队列【调用accept的时候就是从这个接收队列中获取一个握手就绪连接来用。】,准备好之后才能接收握手请求,之后才能接收客户端的请求。然后实际 上connect是客户端选择了一个可用端口,然后向服务器发起握手请求了。同时自己还开了个定时器,如果逾期收不到反馈会重试。客户端发起连接请求之后,三次握手的工作就由双方的内核完成了三次握手成功之后,服务器端会创建一个sock对象,在它上面保存好tcp连接的四元组信息,然后放在接收队列中。再后面就是在这个连接之上的读和写了。用户流程只需要发起读写请求就好了,放到接收缓存或者发送缓存中。真正的读写,重试都由内核从缓存中取数据,或者写入。
            • 首先服务器一方启动后先创建出套接字客户端创建套接字的操作非常简单,只要调用Socket库中的socket程序组件就可以了。和调用解析器一样,调用socket之后,控制流程会转移到socket内部并执行创建套接字的操作,完成之后控制流程又会被移交回应用程序。只不过,socket的内部操作并不像解析器那样简单。
            • 客户端也会先创建一个套接字,然后从该套接字延伸出管道,最后管道连接到服务器端的套接字上
              • Socket、 socket.、套接字(英文也是socket)等看起来非常容易混淆的词,其中小写的socket表示程序组件的名称,大写字母开头的Socket表示库,而汉字的“套接字”则表示管道两端的接口。后面将提到的connect、write、read、close 等就是程序组件的内部操作。,也就是说明**程序组件其实内部就放了一堆方法呗**。当调用Socket库中的程序组件时,应用程序所指定的参数会通过Sacket库的程序组件传递给协议栈,并由协议栈来实际执行相应的操作
              • socket编程的关键函数:socket_create、socket_connect、socket_bind、socket_listen、socket_accept、socket_read、socket_write、socket_close
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第10张图片
            • 套接字创建完成后,协议栈会返回一个描述符,应用程序会将收到的描述符存放在内存中
              • 描述符是用来识别不同的套接字的。我们现在只关注了浏览器访问Web服务器的过程,但实际上计算机中会同时进行多个数据的通信操作,比如可以打开两个浏览器窗口,同时访问两台Web服务器。这时有两个数据收发操作在同时进行,也就需要创建两个不同的套接字。这个例子说明,同一台计算机上可能同时存在多个套接字,在这样的情况下,我们就需要一种方法来识别出某个特定的套接字,这种方法就是描述符。我们可以将描述符理解成**给某个套接字分配的编号。也许光说编号还不够形象,大家可以想象一下在酒店寄存行李的场景,酒店服务人员会给你一个号码牌,向服务人员出示号码牌,就可以取回自己寄存的行李,描述符的原理和这个差不多。当创建套接字后,我们就可以使用这个套接字来执行收发数据的操作了。这时,只要我们出示描述符,协议栈就能够判断出我们希望用哪一个套接字来连接或者收发数据了应用程序是通过“描述符”这一类似号码牌的东西来识别套接字的**。
            • 协议栈首先会分配用于存放一个套接字所需的内存空间。用于记录套接字控制信息的内存空间并不是一开始就存在的,因此我们先要开辟出这样一块空间来,这相当于为控制信息准备一个容器。但光一个容器并没有什么用,还需要往里面存入控制信息。套接字刚刚创建时,数据收发操作还没有开始,因此需要在套接字的内存空间中写入表示这一初始状态的控制信息。到这里,创建套接字的操作就完成了。
            • 计算机内部公同时运行多个程序,如果每个程序都擅自使用内存空间的话,就有可能发生多个程序重复使用同一个内存区域导致数据损坏的问题。为了避免出现这样的问题。操作系统中有一个内存管理模块。它相当于内存的管理员,负责根据程序的申请分配相应的内存空间。确保这些内存空间不会被其他程序使用。因此。分配内存的操作就是向内存管理模块提出申请,请它划分一块内存空间出来
            • 接下来,需要将表示这个套接字的描述符告知应用程序。描述符相当于用来区分协议栈中的多个套接字的号码牌收到描述符之后,应用程序在向协议栈进行收发数据委托时就需要提供这个描述符。由于套接字中记录了通信双方的信息以及通信处于怎样的状态,所以只要通过描述符确定了相应的套接字,协议栈就能够获取所有的相关信息,这样一来,应用程序就不需要每次都告诉协议栈应该和谁进行通信了.
          • (2)连接阶段(总而言之,就是当调用connect进行连接时,协议栈就会执行连接操作。当连接成功后,协议栈会将对方的IP地址和端口号等信息保存在套接字中,这样我们就可以开始收发数据了。描述符:应用程序用来识别套接字的机制IP地址和端口号:客户端和服务器之间用来识别对方套接字的机制):将管道连接到服务器端的套接字上。我们需要委托协议栈将客户端创建的套接字与服务器那边的套接字连接起来。应用程序通过调用Socket库中的名为connect的程序组件来完成这一操作。这里的要点是当调用connect时,需要指定描述符、服务器IP地址和端口号这3个参数
            • 第1个参数,即描述符,就是在创建套接字的时候由协议栈返回的那个描述符。connect会将应用程序指定的描述符告知协议栈,然后协议栈根据这个描述符来判断到底使用哪一个套接字去和服务器端的套接字进行连接,并执行连接的操作。当调用Socket库中的程序组件时,应用程序所指定的参数会通过Sacket库的程序组件传递给协议栈,并由协议栈来实际执行相应的操作。
            • 第2个参数,即服务器IP地址,就是通过DNS服务器查询得到的我们要访问的服务器的IP地址。在DNS服务器那里进行数据收发操作时,双方必须知道对方的IP地址并告知协议栈。这个参数就是那个IP地址了。
            • 第3个参数,即端口号。IP地址是为了区分网络中的各个计算机而分配的数值。因此,只要知道了IP地址,我们就可以识别出网络.上的某台计算机。但是,连接操作的对象是某个具体的套接字,因此必须要识别到具体的套接字才行,而仅凭IP地址是无法做到这一点的。我们打电话的时候,也需要通过“请帮我找一下 某某某”这样的方式来找到具体的某个联系人,而端口号就是这样一种方式。当同时指定IP地址和端口号时,就可以明确识别出某台具体的计算机上的某个具体的套接字。准确地说,IP地址不是分配给每一台设备的,而是分配给设各中安装的网络硬件的。因此,如果一台设备中安装了多个网络硬件,那么就会有多个IP地址
              • 比如 80 端口通常是 Web 服务器用的,22 端口通常是远程登录服务器用的。而对于浏览器(客户端)中的每个标签栏都是一个独立的进程,操作系统会为这些进程分配临时的端口号。
                • TCP 协议里面会有两个端口,一个是浏览器监听的端口(通常是随机生成的),一个是 Web 服务器监听的端口(HTTP 默认端口号是 80, HTTPS 默认端口号是 443)。
              • 能不能只用前面创建套接字时提到的那个描述符而不用IP和端口来识别套接字呢? "这种方法其实是行不通的,因为描述符是和委托创建套接字的应用程序进行交互时使用的,并不是用来告诉网络连接的另-方的,因此另一方并不知道这个描述符。同样地,客户端也无法知道服务器上的描述符。因此,客户端也无法通过服务器端的描述符去确定位于服务器上的某一个套接字。所以,我们需要另外一个对客户端也同样适用的机制,而这个机制就是端口号。如果说描述符是用来在一台计算机内部识别套接字的机制,那么端口号就是用来让通信的另一方能够识别出套接字的机制。当同时指定IP地址和端口号时,就可以明确识别出某台具体的计算机上的某个具体的套接字。既然需要通过端口号来确定连接对象的套接字,那么到底应该使用几号端口呢?网址中好像并没有端口号也不能像IP地址一样去问DNS服务器。其实服务器上所使用的端口号足根据应用的种类事先规定好的,仅此而已。比如Web是80号端口,电子邮件是25号端口65。只要指定了事先规定好的端口号,就可以连接到相应的服务器程序的套接字。也就是说,浏览器访问Web服务器时使用80号端口,这是已经规定好的。实际上根据网址的规则, 是有用来写端口号的地方的, 但实际的网址中很少出现端口号,大部分情况下都省略了。实际上存在通过DNS服务器查询端口号的机制,只能说并没有广泛普及。客户端在创建套接字时,协议栈会为这个套接字随便分配一个端口号66。接下来,当协议栈执行连接操作时,会将这个随便分配的端口号通知给服务器。
          • (3)收发数据(通信阶段): 传递消息:当双方的套接字连接起来后通信准备就完成了。接下来就是将数据送入套接字就可以收发数据了
            • 当套接字连接起来之后,剩下的事情就是只要将数据送入套接字,数据就会被发送到对方的套接字中。当然,应用程序无法直接控制套接字,因此还是要通过Socket库委托协议栈来完成这个操作这个操作需要使用write这个程序组件,具体过程如下。
              • 首先,应用程序需要在内存中准备好要发送的数据。根据用户输入的网址中的域名和域名前的协议种类,由对应的协议(假设用的是HTTP)生成的HTTP请求消息就是我们要发送的数据。
              • 接下来,当调用write时,需要指定描述符和发送数据,然后协议栈就会将数据发送到服务器。由于套接字中已经保存了已连接的通信对象的相关信息,也就是IP和端口号,所以只要通过描述符指定套接字,就可以识别出通信对象,并向其发送数据。
              • 接着,发送数据会通过网络到达我们要访问的服务器。
              • 接下来,服务器执行接收操作,解析收到的数据内容并执行相应的操作,向客户端返回响应消息。当消息返回后,需要执行的是接收消息的操作。接收消息的操作是通过Socket库中的read程序组件委托协议栈来完成的。调用read时需要指定用于存放接收到的响应消息的内存地址,这一内存地址称为接收缓冲区。于是,当服务器返回响应消息时,read就会负责将接收到的响应消息存放到接收方的内存空间也就是接收缓冲区中。由于接收缓冲区是一块位于应用程序内部的内存空间,因此当消息被存放到接收缓冲区中时,就相当于已经转交给了应用程序。
          • (4):断开阶段: 收发数据结束。当浏览器收到数据之后,收发数据的过程就结束了。接下来,我们需要调用Socket库的close程序组件进入断开阶段。最终,连接在套接字之间的管道会被断开,套接字本身也会被删除。断开的过程如下。当数据全部发送完毕后连接的管道将会被断开(断开客户端或者服务器都可以发起断开,管道断开后套接字也会被删除,通信操作就标志结束)
            • Web使用的HTTP协议规定,当Web服务器发送完响应消息之后,应该主动执行断开操作,因此Web服务器会首先调用dlose来断开连接。断开操作传达到客户端之后,客户端的套接字也会进入断开阶段。接下来,当浏览器调用read执行接收数据操作时,read会告知浏览器收发数据操作已结束,连接已经断开。浏览器得知后,也会调用close进入断开阶段。根据应用种类不同,客户端和服务器哪一方先执行lose都有可能。有些应用中是客户端先执行close, 而另外一些应用中则是服务器先执行close.
      • 表示层:主要负责数据格式的转换,如加密解密、转换翻译、压缩解压缩等。
      • 会话层:负责在网络中的两节点之间建立、维持和终止通信,如服务器验证用户登录便是由会话层完成的。
        • 会话层的重要协议:不同的主机用户之间建立会话以及管理会话
          • SSL协议:安全套接字协议
          • TLS协议:传输层安全协议
          • RPC协议:远程过程调用协议
      • 运输层:有时也译为传输层,向应用层的主机进程提供通用的数据传输服务或者网络支持。【传输层的主要任务就是负责向两台终端设备进程之间的通信提供通用的数据传输服务假设我们需要在 A 电脑的进程发一段数据到 B 电脑的进程,我们一般会在代码里使用 socket 进行编程。这时候,我们可选项一般也就TCP 和 UDP 二选一。TCP 可靠,UDP 不可靠。 除非是马总这种神级程序员(早期 QQ 大量使用 UDP),否则,只要稍微对可靠性有些要求,普通人一般无脑选 TCP 就对了。】。 应用进程利用该服务传送应用层报文。“通用的”是指并不针对某一个特定的网络应用,而是多种应用可以使用同一个运输层服务。】
        java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第11张图片
        • 传输层常见的作用或者功能是:
          • 数据分割与重组、纠错【TCP的拆包粘包 】、流量控制、端口寻址等
        • 当设备作为接收⽅时,传输层则要负责把数据包传给应⽤,但是⼀台设备上可能会有很多应⽤在接收或者传输数据,因此需要⽤⼀个编号将应⽤区分开来,这个编号就是端⼝
          运输层主要有以下两种协议:
        • TCP【传输控制协议(Transmission Control Protocol)】:TCP传输控制协议在IP协议的基础上增加了确认重发、滑动窗口和复用等机制,提供了稳定的、安全的、面向连接【传输数据前先建立连接】的字节流【基于字节流的服务没有字节序问题的困扰】服务
          • 或者说TCP有三大特点:【因为IP 层是不可靠的,它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中的数据的完整性,所以如果需要保障网络数据包的可靠性,那么就需要由上层(传输层)的 TCP 协议来负责。】
            • 面向连接【一定是一对一才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的】
              • TCP协议是面向连接的单播协议【单播指的是在数据发送和接收之前通信双方必须在彼此间建立一条连接,一对一的服务,有来言有去语】
            • 可靠【TCP 通过各种机制可以保证一个报文一定能够到达接收端】
            • 基于字节流【字节流可以理解为一个双向的通道里流淌的二进制数据,也就是 01 串 。纯裸 TCP 收发的这些 01 串之间是 没有任何边界 的,你根本不知道到哪个地方才算一条完整消息。所以会发生粘包问题,所以要拆包,你拆包不就按照字节流或者说二进制序列拆开的嘛】
          • TCP 报文头部的格式:
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第12张图片
          • TCP协议控制位:URG:紧急指针字段、ACK:表示确认号有效、SYN:用于发起一个TCP连接。FIN用于断开一个TCP连接。PSH表示接收方需要尽快把数据交给应用层。RST表示重新连接
          • TCP 是面向连接,能保证数据的可靠性交付,因此经常用于:
            • FTP文件传输
            • HTTP / HTTPS
          • fd = socket(AF_INET,SOCK_STREAM,0);其中 SOCK_STREAM,是指使用字节流传输数据,说白了就是TCP 协议
            • 在定义了 socket 之后,我们就可以愉快的对这个 socket 进行操作
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第13张图片
            • 上面就算做是一个纯裸的TCP,肯定是不行的,TCP三大特点【面向连接即三握、可靠的即那一堆机制、基于字节流(字节流可以理解为一个双向的通道里流淌的二进制数据,也就是 01 串 。纯裸 TCP 收发的这些 01 串之间是 没有任何边界 的,你根本不知道到哪个地方才算一条完整消息,没有边界就会出现出界情况,拿多了或者少拿了。)】,所以纯裸 TCP 是不能直接拿来用的,需要 在这个基础上加入一些 自定义的规则 ,用于区分 消息边界
            • 于是我们会把每条要发送的数据都包装一下,比如 加入 消息头【消息头 ,还可以放各种东西,比如消息体是否被压缩过和消息体格式之类的,只要上下游都约定好了,互相都认就可以了,这就是所谓的 协议。每个使用 TCP 的项目,比如咱们的RPC项目,都可能会定义一套类似这样的协议解析标准,他们可能有区别,但原理都类似。于是基于 TCP,就衍生了非常多的协议,比如 HTTP 和 RPC。】 ,消息头里写清楚一个完整的 包长度是多少,根据这个长度可以继续接收数据,截取出来后它们就是我们真正要传输的 消息体
          • TCP 粘包/拆包是怎么发生的?怎么解决这个问题
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第14张图片
            • 发生TCP粘包的原因:【上一个包的内容与下一个包里的数据粘在了一起被错误地当成了一个数据包解析了出来。这就是所谓的粘包。】【用层传到 TCP 协议的数据,不是以消息报为单位向目的主机发送,而是以字节流的方式发送到下游,这些数据可能被切割和组装成各种数据包,接收端收到这些数据包后没有正确还原原来的消息,因此出现粘包现象。】
              • 1.发送的数据小于 TCP 缓冲区大小,TCP将缓冲区中的数据(数据属于多条业务内容)一次发送出去可能就会发生粘包。
              • 2.接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包
            • 发生 TCP 拆包的原因:
              • 1.待发送数据大于最大报文长度,TCP 在传输前将进行拆包。
                • 应用需要传输的数据可能会非常大,如果直接传输就不好控制,因此当传输层的数据包大小超过 MSS(TCP 最大报文段长度) ,就要将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块,而不用重新发送整个数据包。在 TCP 协议中,我们把每个分块称为一个 TCP 段(TCP Segment)。
                  • 如果 HTTP 请求消息比较长,超过了 MSS 的长度,这时传输层 TCP 就需要把应用层的 HTTP 的数据拆解成一块块的数据发送,而不是一次性发送所有数据。
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第15张图片
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第16张图片
                  • MTU:网络层中一个网络包【也就是一个IP报文:传输层的报文或者说数据部分+IP包头】的最大长度,以太网中一般为 1500 字节。【由网络接口层(数据链路层)提供给网络层,一般认为是的MTU(1500),直接传入整个消息,会超过水管的最大承受范围,那么,就需要进行切片,成为一个个数据包,这样消息才能正常通过“水管”。每一层都增加了各自的协议头,那自然网络包的大小就增大了,但物理链路并不能传输任意大小的数据包,所以在以太网中,规定了最大传输单元(MTU)是 1500 字节,也就是规定了单次传输的最大 IP 包大小。
                  • MSS:MSS代表 传输层中TCP 最大报文段长度:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。【应用需要传输的数据可能会非常大,如果直接传输就不好控制,因此当传输层的数据包大小超过 MSS(TCP 最大报文段长度) ,就要将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块,而不用重新发送整个数据包。在 TCP 协议中,我们把每个分块称为一个 TCP 段(TCP Segment)。】
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第17张图片
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第18张图片
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第19张图片
              • 2.发送的数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包。
            • 【如果前后两次 TCP 发的数据都远小于 MSS,比如就几个字节,每次都单独发送这几个字节,就比较浪费网络 io 。】
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第20张图片
              • TCP的 Nagle 算法优化,目的是为了避免发送小的数据包。在 Nagle 算法开启的状态下,数据包在以下两个情况会被发送:【但是如今网络环境比以前好太多,Nagle 的优化帮助就没那么大了,所以一般不用这个算法】
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第21张图片
                • 如果包长度达到MSS(或含有Fin包),立刻发送,否则等待下一个包到来;如果下一包到来后两个包的总长度超过MSS的话,就会进行拆分发送;
                • 等待超时(一般为200ms),第一个包没到MSS长度,但是又迟迟等不到第二个包的到来,则立即发送
            • 解决TCP粘包【实际出现粘包是因为 接收数据端的应用层没有及时读取 TCP Recv Buffer 中的数据,从而不确定消息的边界。接收端在面对"无边无际"的二进制流的时候,根本不知道收了多少 01 才算一个消息。一不小心拿多了就说是粘包。其实粘包根本不是 TCP 的问题,是使用者对于 TCP 的理解有误导致的一个问题。】,所以只要在发送端每次发送消息的时候给消息带上识别消息边界的信息,接收端就可以根据这些信息识别出消息的边界,从而区分出每个消息
              在这里插入图片描述
              • 1.发送端给每个数据包添加包首部,首部中包含数据包的长度,这样接收端在接收到数据后,通过该字段就可以知道每个数据包的实际长度了。
              • 2.发送端将每个数据包设置固定长度,这样接收端每次从读取固定长度的数据把每个数据包拆分开。
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第22张图片
              • 3.可以在数据包之间设置边界,如添加特殊符号,接收端可以通过这个特殊符号来拆分包。
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第23张图片
                • 采用0xfffffe标志位,用来标志一个数据包的开头,又怕发的某个数据里正好有这个内容。所以一般除了这个标志位,发送端在发送时还会加入各种校验字段(校验和或者对整段完整数据进行 CRC 之后获得的数据)放在标志位后面,在接收端拿到整段数据后校验下确保它就是发送端发来的完整数据
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第24张图片
          • TCP协议如何保证可靠性?----TCP主要提供了检验和、序列号/确认应答、超时重传、滑动窗口、拥塞控制和 流量控制等方法实现了可靠性传输。
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第25张图片
            • 检验和:通过检验和的方式,接收端可以检测出来数据是否有差错和异常,假如有差错就会直接丢弃TCP段,重新发送。
            • 序列号/确认应答:序列号的作用不仅仅是应答的作用,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据
              • TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。也就是发送ACK报文,这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发
            • 滑动窗口:滑动窗口既提高了报文传输的效率,也避免了发送方发送过多的数据而导致接收方无法正常处理的异常。
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第26张图片
              • 详细讲一下TCP的滑动窗口?:
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第27张图片
                • 在进行数据传输时,如果传输的数据比较大,就需要拆分为多个数据包进行发送TCP 协议需要对数据进行确认后,才可以发送下一个数据包。这样一来,就会在等待确认应答包环节浪费时间。(为了避免这种情况,TCP引入了窗口概念。窗口大小指的是不需要等待确认应答包而可以继续发送数据包的最大值
                  • TCP 是每发送⼀个数据,都要进⾏⼀次确认应答。只有上一个收到了回应才发送下一个,这样效率会非常低,因此引进了滑动窗口的概念。(其实就是在发送方设立一个缓存区间将已发送但未收到确认的消息缓存起来,假如一个窗口可以发送 5 个 TCP 段,那么发送方就可以连续发送 5 个 TCP 段,然后就会将这 5 个 TCP 段的数据缓存起来,这 5 个 TCP 段是有序的,只要后面的消息收到了 ACK ,那么不管前面的是否有收到 ACK,都代表成功(累计应答),窗口大小(窗口大小就是指不需要等待应答,还可以发送数据的大小。)是由接收方决定的。)
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第28张图片
                • 分组:当发送端与接收端相互传输数据时,不可以一次性(有个最大传输长度MTU存在,当传输的数据大于这个限制时,表示必须分组了,太大了)就将数据传输完毕,会将数据分段,然后再给每段加上首部字段后再去传输,此时**分段后加上首部字段形成的信息包称为分组**,每层都有自己(自己按照自己目的加工出来的)的分组
                • 滑动窗口起到了一个限流的作用,也就是说当前滑动窗口的大小决定了当前 TCP 发送包的速率,而滑动窗口的大小取决于拥塞控制窗口和流量控制窗口的两者间的最小值
            • 超时重传:超时重传是指发送出去的数据包到接收到确认包之间的时间,如果超过了这个时间会被认为是丢包了,需要重传。最大超时时间是动态计算的
            • ARQ 协议: 也是为了实现可靠传输的,ARQ 协议的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组
              • 自动重传请求(Automatic Repeat-reQuest,ARQ)是 OSI 模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ 包括停止等待 ARQ 协议和连续 ARQ 协议
                • 停止等待 ARQ 协议:停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复 ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组。在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第29张图片
                • 连续 ARQ 协议:连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累积确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第30张图片
            • 拥塞控制:在数据传输过程中,可能由于网络状态的问题,造成网络拥堵,此时引入拥塞控制机制,在保证TCP可靠性的同时,提高性能
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第31张图片
              • 详细讲一下拥塞控制?—TCP 一共使用了四种算法来实现拥塞控制:发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量【为了进行拥塞控制,TCP 发送方要维持一个 拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。】。当cwndssthresh时,改用拥塞避免算法
                • 慢开始 (slow-start);慢启动
                  • 不要一开始就发送大量的数据,而是先探测一下网络的拥塞程度。由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个ACK,就将拥塞窗口cwnd大小就加1(单位是MSS)cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。每轮次发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第32张图片
                • 拥塞避免 (congestion avoidance);
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第33张图片
                  • 拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1而不是加倍。这样拥塞窗口按线性规律缓慢增长。
                  • 为了防止cwnd增长过大引起网络拥塞,还需设置一个慢启动阀值ssthresh(slow start threshold)状态变量。当cwnd到达该阀值后,就好像水管被关小了水龙头一样,减少拥塞状态。即当cwnd >ssthresh时,进入了拥塞避免算法。一般来说,慢启动阀值ssthresh是65535字节,cwnd到达慢启动阀值后:每收到一个ACK时,cwnd = cwnd + 1/cwnd,当每过一个RTT时,cwnd = cwnd + 1
                • 快速重传 (fast retransmit);
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第34张图片
                  • 拥塞发生:如果是发生了RTO超时重传,就会使用拥塞发生算法.还有更好的处理方式,就是快速重传。发送方收到3个连续重复的ACK时,就会快速地重传,不必等待RTO超时再重传
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第35张图片
                  • 我们可以剔除一些不必要的拥塞报文,提高网络吞吐量。比如接收方在收到一个失序的报文段后就立即发出重复确认,而不要等到自己发送数据时捎带确认。快重传规定:发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第36张图片
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第37张图片
                • 快速恢复 (fast recovery):快速重传和快速恢复算法一般同时使用。快速恢复算法认为,还有3个重复ACK收到,说明网络也没那么糟糕,所以没有必要像RTO超时那么强烈。
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第38张图片
                  • 主要是配合快重传。当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半(为了预防网络发生拥塞),但接下来并不执行慢开始算法,因为如果网络出现拥塞的话就不会收到好几个重复的确认,收到三个重复确认说明网络状况还可以
                  • 真正的快速算法如下:
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第39张图片
            • 流量控制用来解决发送方一直发送数据,但是接收方处理不过来怎么办【流量控制是为了控制发送方发送速率,保证接收方来得及接收】?如果主机A 一直向主机B发送数据,不考虑主机B的接受能力,则可能导致主机B的接受缓冲区满了而无法再接受数据【双方在通信的时候,发送方的速率与接收方的速率是不一定相等,如果发送方的发送速率太快,会导致接收方处理不过来。如果接收方处理不过来的话,就只能把处理不过来的数据存在 接收缓冲区(Receiving Buffers) 里(失序的数据包也会被存放在缓存区里)。如果缓存区满了发送方还在狂发数据的话,接收方只能把收到的数据包丢掉。出现丢包问题的同时又疯狂浪费着珍贵的网络资源。因此,我们需要控制发送方的发送速率,让接收方与发送方处于一种动态平衡才好。】,从而会导致大量的数据丢包,引发重传机制。而在重传的过程中,若主机B的接收缓冲区情况仍未好转,则会将大量的时间浪费在重传数据上,降低传送数据的效率。所以引入流量控制机制,主机B通过告诉主机A自己接收缓冲区的大小,来使主机A 控制发送的数据量流量控制与TCP协议报头中的窗口大小** 有关
              • 如果接收方处理不过来,发送方就会触发重试机制再次发送数据,然而这个是有性能损耗的,为了解决这个问题,TCP 就提出了流量控制,为的就是让发送方知道接受方的处理能力。也就是说,每次接收方接受到数据后会将剩余可处理数据的大小告诉发送方(比如接受方滑动窗口可用大小为400字节,发送方发送过来100字节的数据,那么接收方剩余可用滑动窗口大小就为300字节,这是发送方就知道下次返送数据的大小范围了。)。
              • 接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据
                • TCP 为全双工(Full-Duplex, FDX)通信,双方可以进行双向通信,客户端和服务端既可能是发送端又可能是服务端。因此,两端各有一个发送缓冲区与接收缓冲区,两端都各自维护一个发送窗口和一个接收窗口。接收窗口大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。通信双方的发送窗口和接收窗口的要求相同
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第40张图片
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第41张图片
              • 但是这里有一个问题,数据会存放在缓冲区,但是这个缓冲区是操作系统控制的,当系统繁忙的时候,会缩减缓冲区减小,可能就会造成丢包的问题(上面那个虽然说是主机B的接受缓冲区满了无法接收数据才导致大量数据丢失,但是这里缩减缓冲区导致丢包其实和缓冲区满一样)。我们会发现,这个问题发生的原因就是减少了缓存,又收缩了窗口大小,所以 TCP 是不允许同时减少缓存⼜收缩窗⼝的
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第42张图片
        • TCP三握四挥:三次握手、四次挥手
          • 三次握手有四种状态、四次挥手中有七种状态,总共11中状态
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第43张图片
            • 三次握手时,除了四个状态,还有知识点就是:客户端发的包,其实发的是SYN+seq【seq指的是ISN码,一个用于识别的码】;服务端回一个SYN+ACK+seq+ack【第一次客户端发的seq和服务端回的seq没有一毛钱关系,但是回的ack=客户端发的seq+1】;客户端再次发ACK+seq+ack【这个ack=服务端回的那个seq+1,seq=客户端第一次发的seq+1】
              • 可以用wireshark抓包进行分析:安装软件打开有波形图的网络连接【虚拟机一般对应的是vNet8】,可以通过最上面的过滤栏输入tcp.port == 22,这种进行过滤,然后就可以抓包找tcp协议中走的是22端口的那些数据
            • 四次挥手时,除了七个状态,还有知识点就是:断开连接是建立在原来的连接之后的数据传输基础之上的。
          • 光说TCP可靠,那为什么TCP可靠,就是因为下面TCP 的三次握手机制(TCP 建立连接的过程):TCP 传输数据之前,要先三次握手建立连接【在 HTTP 传输数据之前,首先需要 TCP 建立连接,TCP 连接的建立,通常称为三次握手】【三次握手目的是保证双方都有发送和接收的能力
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第44张图片
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第45张图片
            • 第一次握手【客户端–--->发送带有 SYN 标志的数据包–一次握手–---->服务端】:除了图中一握做的四件事之外(客户端向服务器发一个同步报文其实也就是将同步位 SYN 设置为 1),Client的TCP进程创建一个传输控制块 TCB ,然后向Server发出连接请求报文段,客户端进入同步已发送状态
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第46张图片
              • 连接刚开始时,客户端和服务器都处于CLOSED状态。先是服务端主动监听某个端口,并且服务器处于LISTEN状态。然后客户端随机初始化序列号seq=x,然后将这个随机初始化的序列号置于TCP首部的序号字段中,同时把SYN标志位置为1【SYN=1表示这是一个连接请求的报文】,接着把第一个SYN请求连接报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于SYN-SENT状态
            • 第二次握手【服务端–----->发送带有 SYN/ACK 标志的数据包–二次握手–------>客户端】:服务器收到连接请求报文段,如果同意建立连接,则向客户端发送同步确认报文。在确认报文段中同步位 SYN=1、确认位 ACK=1、确认号 ack=x+1,同时也为自己选择一个初始序列号 seq=y,这时服务器进入 SYN-RCVID 状态
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第47张图片
              • 服务端收到客户端的SYN报文后,首先服务端也随机初始化自己的序列号seq=y并将这个序列号填入TCP首部的序号字段中,然后再把TCP首部的确认应答号字段填入client_isn + 1【也就是ack,这个确认应答号不就是上一次的seq + 1嘛,不就是x+1】,并接着把SYN和ACK标志位置为1.最后把该不包含应用层数据的报文发给客户端,之后服务端处于SYN-RCVD状态
            • 第三次握手【客户端–----->发送带有带有 ACK 标志的数据包–三次握手–----->服务端】:客户端收到 服务器的确认以后,再向服务器发出确认报文。确认报文 ACK=1、确认号ack=y+1。这时客户端进入到 ESTAB-LISHED 状态。当服务器接收到客户端的确认后,服务器也进入 ESTAB-LISHED 状态。连接建立完成
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第48张图片
              • 客户端收到服务器端的同步确认报文后,还要先生成一个随机序列号seq = x + 1,然后向服务端回应最后一个应答报文,首先该应答报文TCP首部ACK标志位置为1,其次确认应答号字段ack=上一次的随机序列号seq + 1 = y + 1,最后把确认报文发给服务端,这次报文可携带客户到服务器的数据,之后客户端处于ESTABLISHED状态
              • 服务器收到确认报文后也进入ESTABLISHED状态
              • 第三次握手是可以携带数据的,前两次握手是不可以携带数据的。一旦完成三次握手,双方都处于 ESTABLISHED 状态,此时连接就已建立完成,客户端和服务端就可以相互发送数据了。
          • 这个所谓的连接,只是双方计算机里维护一个状态机,在连接建立的过程中,双方的状态变化时序图就是左右那些框里的字母。
            • TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第49张图片
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第50张图片
            • 可以深入看看OS的源码中的不同样式的三次握手:在 TCP 三次握手过程中,当服务器收到客户端的 SYN 包后,内核会把该连接存储到半连接队列,然后再向客户端发送 SYN+ACK 包,接着客户端会返回 ACK,服务端收到第三次握手的 ACK 后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其增加到全连接队列 ,等待进程调用 accept() 函数时把连接取出来。也就说,全连接队列指的是服务器与客户端完了 TCP 三次握手后,还没有被 accept() 系统调用取走连接的队列。
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第51张图片
            • 一握:tcp_connect(…)方法负责创建一个TCP连接
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第52张图片
          • 为什么需要三次握手【三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。】,而不是两次或者四次:主要有三个原因【通过三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。】
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第53张图片
            • 原因一:三次握手的首要原因是为了防止已过期或者已经失效的连接请求报文突然又传送到服务器,因而产生错误和资源浪费
              • 如果客户端连续发送多次 SYN 建⽴连接的报⽂,如果出现了网络拥堵,可能会有旧连接先于新连接到达的情况,就可能会出现连接覆盖,要避免这种情况,最少需要三次握手【三次握手可以保证在被动发起方发送数据前,也就是建立连接之前,阻止掉历史连接,这样就不会造成资源浪费】
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第54张图片
              • 在双方两次握手即可建立连接的情况下,假设客户端发送 A 报文段请求建立连接,由于网络原因造成 A 暂时无法到达服务器服务器接收不到请求报文段就不会返回确认报文段,客户端在长时间得不到应答的情况下重新发送请求报文段 B,这次 B 顺利到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,客户端在收到 确认报文后也进入 ESTABLISHED 状态,双方建立连接并传输数据,之后正常断开连接。此时姗姗来迟的 之前那个A 报文段才到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,但是已经进入 CLOSED 状态的客户端无法再接受确认报文段,更无法进入 ESTABLISHED 状态,这将导致服务器长时间单方面等待,造成资源浪费
            • 原因二:(三次握⼿正好避免资源浪费,三次握⼿就已经是理论上建立可靠连接的最小次数了,所以不需要更多的连接)三次握手才能让双方均确认自己和对方的发送和接收能力都正常Client确认自己收发、对方收发能力正常+Server确认自己收发、对方收发能力正常
              • 第一次握手:客户端只是发送处请求报文段,什么都无法确认,而服务器可以确认“自己收、客户端发”能力正常
              • 第二次握手:客户端可以确认**“自己发、自己收、服务端收、服务端发”能力正常**;Server 确认了:对方发送正常,自己接收正常
              • 第三次握手:服务器可以确认“自己发、客户端收”能力正常,对方发送能力和接收能力正常
            • 原因三:告知对方自己的初始序号值,并确认收到对方的初始序号值(同步双⽅初始序列号):
              • TCP 实现了可靠的数据传输,原因之一就是 TCP 报文段中维护了序号字段和确认序号字段通过这两个字段双方都可以知道在自己发出的数据中,哪些是已经被对方确认接收的,这样一来一回,才能确保双方的初始序列号能被可靠的同步。。这两个字段的值会在初始序号值得基础递增,如果是两次握手,只有发起方的初始序号可以得到确认,而另一方的初始序号则得不到确认
              • 四次握手其实也能够可靠的同步双方的初始化序号,但由于第二步和第三步可以优化成一步,所以就成了三次握手。而两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收
          • 为什么要三次握手,而不是四次?五次…
            • 因为三次握手已经可以确认双方的发送接收能力正常,双方都知道彼此已经准备好,而且也可以完成对双方初始序号值的确认,也就无需再第四次握手了。
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第55张图片
          • 第一次握手丢失了,会发生什么?
            • 当客户端想和服务端建立 TCP 连接的时候,首先第一个发的就是 SYN 报文,然后进入到 SYN_SENT 状态。在这之后,如果客户端迟迟收不到服务端的 SYN-ACK 报文(第二次握手),就会触发「超时重传」机制,重传 SYN 报文
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第56张图片
          • 第二次握手丢失了,会发生什么?
            • 因为第二次握手报文里是包含对客户端的第一次握手的 ACK 确认报文,所以,如果客户端迟迟没有收到第二次握手,那么客户端就觉得可能自己的 SYN 报文(第一次握手)丢失了,于是客户端就会触发超时重传机制,重传 SYN 报文
          • 第三次握手丢失了,会发生什么?
            • 因为这个第三次握手的 ACK 是对第二次握手的 SYN 的确认报文,所以当第三次握手丢失了,如果服务端那一方迟迟收不到这个确认报文,就会触发超时重传机制,重传 SYN-ACK 报文,直到收到第三次握手,或者达到最大重传次数
          • 第 2 次握手传回了 ACK,为什么还要传回 SYN?
            • 接收端传回发送端所发送的 ACK 是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传 SYN 则是为了建立并确认从服务端到客户端的通信。”SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递
          • 三握过程中常见问题:
            • 建立一个 TCP 连接【用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。】是需要客户端与服务器端达成(用于保证可靠性和流量控制维护的某些状态信息:Socket、序列号和窗口大小)的共识。这些信息的组合就称为连接。
              • Socket:由 IP 地址和端口号组成【TCP 四元组可以唯一的确定一个连接
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第57张图片
              • 序列号:用来解决乱序问题等
              • 窗口大小:用来做流量控制
            • TCP 半连接队列和全连接队列:
              • 服务端收到客户端发出的 SYN 请求后,会把这个连接信息存储到半链接队列(SYN 队列)。然后服务端收到第三次握⼿的 ACK 后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到全连接队列(accept 队列),等待进程调⽤ accept 函数时把连接取出来。这两个队列都是有大小限制的,当超过容量后就会将链接丢弃,或者返回 RST 包。
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第58张图片
            • 什么是 SYN洪泛攻击?如何防范?----检测:当在服务器上看到大量的半连接状态时,特别是源 IP 地址是随机的,基本上可以断定这是一次 SYN 攻击。
              • SYN洪泛攻击属于 DOS 攻击的一种,它利用 TCP 协议缺陷,通过发送大量的半连接请求,耗费 CPU 和内存资源,大概原理是:
                • 在三次握手过程中,服务器发送 [SYN/ACK] 包(第二个包)之后、收到客户端的 [ACK] 包(第三个包)之前的 TCP 连接称为半连接(half-open connect),此时服务器处于 SYN_RECV(等待客户端响应)状态。如果接收到客户端的 [ACK],则 TCP 连接成功,如果未接受到,则会不断重发请求直至成功。
                • SYN 攻击的攻击者在短时间内伪造大量不存在的 IP 地址,向服务器不断地发送 [SYN] 包,服务器回复 [SYN/ACK] 包,并等待客户的确认。由于源地址是不存在的,服务器需要不断的重发直至超时。
                • 这些伪造的 [SYN] 包将长时间占用未连接队列,影响了正常的 SYN,导致目标系统运行缓慢、网络堵塞甚至系统瘫痪。
              • 防范:
                • 通过防火墙、路由器等过滤网关防护。
                • 通过加固 TCP/IP 协议栈防范,如增加最大半连接数,缩短超时时间
                • SYN cookies技术。SYN Cookies 是对 TCP 服务器端的三次握手做一些修改,专门用来防范 SYN 洪泛攻击的一种手段。
            • 三次握手连接阶段,最后一次ACK包丢失,会发生什么?
              • 服务端:第三次的ACK在网络中丢失,那么服务端该TCP连接的状态为SYN_RECV,并且会根据 TCP的超时重传机制,会等待3秒、6秒、12秒后重新发送SYN+ACK包,以便客户端重新发送ACK包。 如果重发指定次数之后,仍然未收到 客户端的ACK应答,那么一段时间后,服务端自动关闭这个连接
              • 客户端:客户端认为这个连接已经建立,如果客户端向服务端发送数据,服务端将以RST包(Reset,标示复位,用于异常的关闭连接)响应。此时,客户端知道第三次握手失败。
          • TCP 的四次挥手过程?
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第59张图片
            • 第一次挥手:客户端向服务端发送一个TCP首部FIN标志被置为1的连接释放报文段FIN报文,说我客户端打算关闭连接,(这个连接释放报文段首部的终止控制位FIN=1,ACK=1),主动关闭连接,此时客户端进入FIN-WAIT-1(终止等待1)状态,同时等待服务端的确认:
              • 序列号 seq = u,即客户端上次发送的(确认报文)报文的最后一个字节的序号 + 1
              • 确认号 ack = k, 即服务端上次发送的报文的最后一个字节的序号 + 1
            • 第二次挥手:服务端收到客户端的连接释放报文后,服务端立即发出确认报文段(ACK=1),序列号 seq = k(等于服务端发送数据的最后一个序号加1),确认号 ack = u + 1。此时服务端进入CLOSE-WAIT(关闭等待)状态
              • 这时 TCP 连接处于半关闭状态,即客户端到服务端的连接已经释放了,但是服务端到客户端的连接还未释放。这表示客户端已经没有数据发送了,但是服务端可能还要给客户端发送数据。
            • 第三次挥手: 服务端向客户端发送连接释放报文(FIN=1,ACK=1)(客户端收到服务器的确认报文后进入FIN-WAIT-2(终止等待2)状态,继续等待服务端处理完数据并发出连接释放报文段),服务端主动关闭连接,同时等待客户端的确认。若服务端已经没有数据要发送,服务端就会向客户端发送连接释放报文段FIN报文,段首部的终止控制位 FIN=1,序号 seq=w(半关闭状态可能又发送了一些数据),确认号 ack=u+1,这时服务端进入 LAST-ACK(最后确认)状态,等待客户端的确认。
              • 序列号 seq = w,即服务端上次发送的报文的最后一个字节的序号 + 1。
              • 确认号 ack = u + 1,与第二次挥手相同,因为这段时间客户端没有发送数据
            • 第四次挥手:客户端收到服务端的连接释放报文FIN报文后,立即回应发出确认报文(确认段中确认位ACK=1)序列号 seq = u + 1确认号为 ack = w + 1。然后客户端就进入了 TIME-WAIT(时间等待) 状态。而 服务端只要收到客户端发出的确认,就立即进入 CLOSED 状态,至此服务端已经完成连接的关闭注意此时客户端到 TCP 连接还没有释放,必须经过 2*MSL(最长报文段寿命)的时间后,才进入 CLOSED 状态,至此客户端也完成连接的关闭
              • 此时,注意此时客户端到 TCP 连接还没有释放,必须经过 2*MSL(最长报文段寿命)的时间后,才进入 CLOSED 状态。而**服务端只要收到客户端发出的确认,就立即进入 CLOSED 状态**。可以看到,服务端结束 TCP 连接的时间要比客户端早一些。
              • 主动关闭连接的,才有TIME WAIT状态
              • 2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接收到了服务端重发的 FIN 报文,那么 2MSL 时间会被重置
                • 为什么客户端的 TIME-WAIT 状态必须等待 2MSL ?主要有两个原因:
                  • 确保 ACK 报文能够到达服务端被服务端接收从而正确关闭连接,从而使服务端正常关闭连接。第四次挥手时,客户端第四次挥手的 ACK 报文不一定会到达服务端。服务端会 超时重传 FIN/ACK 报文,此时如果客户端已经断开了连接,那么就无法响应服务端的二次请求,这样服务端迟迟收不到 FIN/ACK 报文的确认,就无法正常断开连接。MSL 是报文段在网络上存活的最长时间。客户端等待 2MSL 时间,即「客户端 ACK 报文 1MSL 超时 + 服务端 FIN 报文 1MSL 传输」,就能够收到服务端重传的 FIN/ACK 报文,然后客户端重传一次 ACK 报文,并重新启动 2MSL 计时器。如此保证服务端能够正常关闭。,如果服务端重发的 FIN 没有成功地在 2MSL 时间里传给客户端,服务端则会继续超时重试直到断开连接。【因为这个 ACK 是有可能丢失的,会导致服务器收不到对 FIN-ACK 确认报文。假设客户端不等待 2MSL ,而是在发送完 ACK 之后直接释放关闭,一但这个 ACK 丢失的话,服务器就无法正常的进入关闭连接状态。】
                  • 防止已失效的连接请求报文段出现在之后的连接中。TCP 要求在 2MSL 内不使用相同的序列号。客户端在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以保证本连接持续的时间内产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。或者即使收到这些过时的报文,也可以不处理它。【】
                    java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第60张图片
              • TIME_WAIT 是服务器端的状态?还是客户端的状态?
                • TIME_WAIT 是主动断开连接的一方会进入的状态,**一般情况下,都是客户端所处的状态;**服务器端一般设置不主动关闭连接。
                • TIME_WAIT 需要等待 2MSL,在大量短连接的情况下,TIME_WAIT会太多,这也会消耗很多系统资源。对于服务器来说,在 HTTP 协议里指定 KeepAlive(浏览器重用一个 TCP 连接来处理多个 HTTP 请求),由浏览器来主动断开连接,可以一定程度上减少服务器的这个问题。
              • TIME-WAIT 状态过多会产生什么后果?怎样处理?
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第61张图片
                • 从服务器来讲,短时间内关闭了大量的Client连接,就会造成服务器上出现大量的TIME_WAIT连接,严重消耗着服务器的资源,此时部分客户端就会显示连接不上
              • 从客户端来讲,客户端TIME_WAIT过多,就会导致端口资源被占用,因为端口就65536个,被占满就会导致无法创建新的连接
          • 四次挥手的问题们:
            • 为什么连接的时候是三次握手,关闭的时候却是四次握手?(或者说为什么是四次握手)
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第62张图片
              • 服务器在收到客户端的 FIN 报文段后,可能还有一些数据要传输,所以不能马上关闭连接,但是会做出应答,返回 ACK 报文段.【任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。A 和 B 打电话,通话即将结束后,A 说“我没啥要说的了”,B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话,于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”,A 回答“知道了”,这样通话才算结束。。】
              • 接下来可能会继续发送数据,在数据发送完后,服务器会向客户单发送 FIN 报文,表示数据已经发送完毕,请求关闭连接。服务器的ACK和FIN一般都会分开发送,从而导致多了一次,因此一共需要四次挥手。
            • 如果已经建立了连接,但是客户端出现故障了怎么办?(如果**三次握手阶段、四次挥手阶段的包丢失了怎么办?如“服务端重发 FIN丢失**”的问题。)
              • 通过**定时器 + 超时重试机制**,尝试获取确认,直到最后会自动断开连接(TCP 设有一个保活计时器。服务器每收到一次客户端的数据,都会重新复位这个计时器,以Linux服务器为例,时间通常是设置为 2 小时。若 2 小时还没有收到客户端的任何数据,服务器就开始重试每隔 75 秒(默认)发送一个探测报文段,若一共发送 10 个探测报文后客户端依然没有回应,那么服务器就认为连接已经断开了。)
                java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第63张图片
        • UDP:提供无连接的、尽最大努力的数据传输服务,但不保证数据传输的可靠性。UDP 用于对高速传输和实时性有较高要求的通信。TCP 和 UDP 应该根据应用目的按需使用。
          • UDP 的头部格式
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第64张图片
          • UDP 相对来说就很简单,简单到只负责发送数据包,不保证数据包是否能抵达对方,但它实时性相对更好,传输效率也高
          • UDP 面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于:
            • 包总量较少的通信,如 DNS 、SNMP、DHCP 协议【动态主机配置协议,动态配置 IP 地址等】
            • 视频、音频等多媒体通信
            • 广播通信
          • UDP不会粘包:UDP是基于数据报是指无论应用层交给 UDP 多长的报文,UDP 都照样发送,即一次发送一个报文。至于如果数据包太长,需要分片,那也是IP层的事情,大不了效率低一些。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。而接收方在接收数据报的时候,也不会像面对 TCP 无穷无尽的二进制流那样不清楚啥时候能结束。正因为基于数据报和基于字节流的差异,TCP 发送端发 10 次字节流数据,而这时候接收端可以分 100 次去取数据,每次取数据的长度可以根据处理能力作调整;但 UDP 发送端发了 10 次数据报,那接收端就要在 10 次收完,且发了多少,就取多少,确保每次都是一个完整的数据报。并且在报头中有16bit用于指示 UDP 数据报文的长度,假设这个长度是 n ,以此作为数据边界。因此在接收端的应用层能清晰地将不同的数据报文区分开,从报头开始取 n 位,就是一个完整的数据报,从而避免粘包和拆包的问题。
          • TCP和UDP的区别?
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第65张图片
            • TCP面向连接(如打电话要先拨号建立连接) ;UDP是无连接的,即发送数据之前不需要
            • TCP提供可靠的服务。也就是说,通过TCP连接传送的数据【TCP 提供可靠的传输服务,TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制】,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
            • TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的;UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
            • 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
            • TCP首部开销20字节;UDP的首部开销小,只有8个字节
      • 网络层:选择合适的路由和交换结点,确保数据及时从一个设备传送到另一个设备(传输数据)。主要包括IP协议。【传输层作为应用间数据传输的媒介,帮助实现应用到应用的通信,而实际的传输功能就交给下一层,也就是网络层(Internet Layer)。】
        • 网络层最常使用的是 IP 协议(Internet Protocol),IP 协议会将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文,如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文。
          java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第66张图片
          • ip的网络包的报文如下:
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第67张图片
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第68张图片
          • ip报文头部:
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第69张图片
            • 假设客户端有多个网卡,就会有多个 IP 地址,那 IP 头部的源地址应该选择哪个 IP 呢?【这个时候就需要根据路由表规则,来判断哪一个网卡作为源地址 IP。在 Linux 操作系统,我们可以使用 route -n 命令查看当前系统的路由表。】
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第70张图片
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第71张图片
          • IP协议有两个重要的作用或者叫能力:
            • 寻址能力:在寻址的过程中,先匹配到相同的网络号(表示要找到同一个子网),才会去找对应的主机。【IP 协议的寻址作用是告诉我们去往下一个目的地该朝哪个方向走
              java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第72张图片
            • 路由:实际场景中,两台设备并不是用一条网线连接起来的,而是通过很多网关、路由器、交换机等众多网络设备连接起来的,那么就会形成很多条网络的路径,因此当数据包到达一个网络节点,就需要通过路由算法决定下一步走哪条路径
              • 路由协议分为静态路由协议和动态路由协议
                • 静态路由协议:需要手动配置。优点是生效速度快、执行效率高、通讯率高;缺点是操作复杂
                • 动态路由协议:不需要手动配置,路由自动学习【你敢来一次,以后你来我就把你的轨迹脚印给缓存下来】。优点是自动记录自动学习路由条目,方便;生效慢、效率低
              • 路由则是根据寻址结果也就是下一个目的地选择路径。寻址更像在导航,路由更像在操作方向盘。
                • 首先,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的 FCS 进行错误校验。如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。总的来说,路由器的端口都具有 MAC 地址,只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃。完成包接收操作之后,路由器就会去掉包开头的 MAC 头部。MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃。路由器会根据 MAC 头部后方的 IP 头部中的内容进行包的转发操作。【查询路由表判断转发目标。每个条目的子网掩码和 192.168.1.100 IP 做 & 与运算,得到的结果与对应条目的目标地址进行匹配,如果匹配就会作为候选转发目标,如果不匹配就继续与下个条目进行路由匹配。实在找不到匹配路由时,就会选择默认路由,路由表中子网掩码为 0.0.0.0 的记录表示「默认路由」
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第73张图片
                • 子网掩码:一个32位字段的数值,利用这个字段可以获得一个范围较小的可以实际使用的网络【利用子网掩码确定网段、利用子网掩码计算主机(先用2^N,N代表主机数,计算出最多容纳的主机数,然后掐头去尾,掐头去掉192.168.0.0这个表示一个网络段范围,去尾表示广播地址:192.168.0.255)】,子网掩码的好处或者作用是节约IP地址资源以及减少寻址空间;子网掩码分类为A、B、C【A:255.0.0.0、B:255.255.0.0、C:255.255.255.0,后面的.0代表一个网络段或者范围而不是一个具体的地址哦,别忘记啦】;子网掩码有两种表示方式【点分二进制方法表示,比如255.255.255.0。另一种就是CIDR表示方法,比如192.168.0.1/24,/24表示这个IP地址段中网络位占了24位,3个字节】;判断两个IP地址是否属于同一个子网,把这俩分别跟子网掩码相与,如果与结果相同则表示这俩在一个子网中,路由器寻址就是按照这个原理算的;子网划分/网络规划,来避免IP地址资源的浪费:【C类地址常用】
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第74张图片
              • 目标地址和子网掩码都是 0.0.0.0,这表示默认网关,如果其他所有条目都无法匹配,就会自动匹配这一行。并且后续就把包发给路由器,Gateway 即是路由器的 IP 地址
        • 此外,IP中还包括ICMP协议和ARP协议
          • ICMP用于告知网络包传送过程中产生的错误以及各种控制消息
            • PING其实就是向目的主机发送多个 ICMP 回送请求报文,PING 主要的作用就是测试在两台主机之间能否建立连接,如果 PING 不通就无法建立连接
              • 如果没有响应则无法建立连接
              • 如果有响应就可以根据目的主机返回的回送报文的时间和成功响应的次数估算出数据包往返时间及丢包率
          • ARP用于根据IP地址查询相应的以太网MAC地址。ARP地址解析协议
        • 网络包:网络中的数据会被切分成几十字节到几千字节的小块,每一个小数据块被称为一个包。如果 IP 报文大小超过 MTU(以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文。
        • 世界上有很多设备,⽹络层需要有区分设备的编号。我们⼀般⽤ IP 地址给设备进⾏编号。IP地址由三部分组成:IP地址的类别+网络标识(网络位,NetWork ID)+主机标识(也叫主机位,Host ID)对于 IPv4 协议, IP 地址共 32 位,分成了四段(比如,192.168.100.1),每段是 8 位,一个字节。只有一个单纯的 IP 地址虽然做到了区分设备,但是寻址起来就特别麻烦,全世界那么多台设备,难道一个一个去匹配?这显然不科学。因此,需要将 IP 地址分成两种意义【需要配合子网掩码才能算出 IP 地址 的网络号和主机号,比如IP地址为10.100.122.0/24,/24表示子网掩码255.255.255.0】:将 IP地址10.100.122.2 和 255.255.255.0 进行按位与运算,就可以得到网络号和主机号
          java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第75张图片
          • 一个是网络号网络号负责标识该 IP 地址是属于哪个子网的
            • 在寻址的过程中,先匹配到相同的网络号(表示要找到同一个子网),才会去找对应的主机。
          • 一个是主机号主机号负责标识同一子网下的不同主机
        • IP地址一般可分为五类:左高右低。
          • A类【A类地址中网络标识占一个字节,最高位为0,A类的网络地址有128=2^ 7个,允许支持127个网络,每个网络允许大约1670万台≈2^ 24主机存在,通常A类地址用于网络运营商或者超大公司。A类地址的分类开始字段:000-127】、
          • B类【B类地址最高两位为10表示网络标识,前两个字节表示网络位,后两个字节表示主机位,B类地址允许有2^ 14 =16000个网络,每个网络允许大约有66000≈2^ 16台主机,通常用于节点比较多的网络,区域网络。B类地址的分类开始字段:128-191】、
          • C类【网络标识是最高三位,为110,网络标识占3个字节,主机标识占一个字节,C类地址支持大约20万个≈2^24个网络,每个网络允许254台主机,因为有两类特殊的IP地址用不了,0通常表示不能分配主机,表示地址段。255也不能分配主机,255表示广播地址。通常用于小型网络/小型局域网/办公室。C类地址的开始字段:192-233】、
          • D类【表示多播地址,高位为1110表示网络标识,后24位表示多播地址。D类地址的分类开始字段:224-239】、E类【保留地址,1111.分类开始字段为:240-255】
        • 特殊的IP地址:广播地址:192.168.1.255、192.168.0.255;子网掩码:255.0.0.0、255.255.0.0、255.255.255.0;回环地址:127.0.0.1;全部网段:0.0.0.0,可以表示任意一个IP地址;DNS地址:114.114.114.114、233.5.5.5、233.6.6.6、1.2.4.8;DHCP分配地址:169.254.0.0,表示路由器假死,重启一下就行;组播地址:224.0.0.1;网关地址:192.168.0.1、198.168.0.254二选一作为网关地址;表示当前网络:192.168.0.100;表示当前你所在的网络:192.168.0.0
        • 路由器:局域网和局域网之间,通过路由器通信。路由器也叫做三层设备。网关就是路由器。【网关就是一个网络通向其他网络的IP地址】
          • 路由器也可以有效的屏蔽交换网络中的广播风暴问题
          • 路由器的分类【网件、TP/D-LINK、华为、水星】、家用/企业级的区别
          • 路由器记录维护一个IP地址列表【IP地址叫做逻辑地址,逻辑地址通常可以改变】。如果两台主通信时,如果目标主机在IP地址列表中,路由器就根据列表记录转发这条数据给目标主机。如果发送的数据不在IP地址列表中,则路由器丢弃这条数据
          • route -n可以查看路由条目
      • 数据链路层:数据链路层通常简称为链路层。将网络层传下来的IP数据包组装成帧,并再相邻节点的链路上传送帧。【MAC在两点传输 】
        • 每⼀台设备的⽹卡都会有⼀个 MAC 地址,它就是⽤来唯⼀标识设备的。路由器计算出了下⼀个⽬的地 IP 地址,再通过 ARP 协议找到该⽬的地的 MAC 地址,这样就知道这个 IP 地址是哪个设备的了。路由器就是通过数据链路层来知道这个 ip 地址是属于哪个设备的,数据链路层主要为⽹络层提供链路级别传输的服务
          • 生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部。
          • MAC:MAC 地址也有一些别称,如 LAN 地址、物理地址、以太网地址等。
          • MAC网络包的报文:
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第76张图片
          • MAC头部:
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第77张图片
        • 生成了 IP 头部之后,接下来要交给网络接口层(Link Layer)在 IP 头部的前面加上 MAC 头部,并封装成数据帧(Data frame)发送到网络上。所以说,网络接口层主要为网络层提供「链路级别」传输的服务,负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备
          • MAC 发送方和接收方如何确认?
            • 发送方的 MAC 地址获取就比较简单了,MAC 地址是在网卡生产时写入到 ROM 里的,只要将这个值读取出来写入到 MAC 头部就可以了
            • 接收方的 MAC 地址就有点复杂了,只要告诉以太网对方的 MAC 的地址,以太网就会帮我们把包发送过去,那么很显然这里应该填写对方的 MAC 地址。所以先得搞清楚应该把包发给谁,这个只要查一下路由表就知道了。****在路由表中找到相匹配的条目,然后把包发给 Gateway 列中的 IP 地址就可以了
          • 如何获取对方的 MAC 地址呢?
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第78张图片
            • 每次都要广播获取,这不是很麻烦吗?还扰民
              • 在后续操作系统会把本次查询结果放到一块叫做 ARP 缓存的内存空间留着以后用,不过缓存的时间就几分钟。也就是说,在发包时:
                • 先查询 ARP 缓存,如果其中已经保存了对方的 MAC 地址,就不需要发送 ARP 查询,直接使用 ARP 缓存中的地址。
                  java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第79张图片
                  在这里插入图片描述
                • 而当 ARP 缓存中不存在对方 MAC 地址时,则发送 ARP 广播查询。
          • 什么是以太网呢?以太网就是一种在「局域网」内,把附近的设备连接起来,使它们之间可以进行通讯的技术。
            • 电脑上的以太网接口,Wi-Fi接口,以太网交换机、路由器上的千兆,万兆以太网口,还有网线,它们都是以太网的组成部分
            • 以太网在判断网络包目的地时和 IP 的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,而 MAC 头部就是干这个用的,所以,在以太网进行通讯要用到 MAC 地址。
            • MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息,我们可以通过 ARP 协议获取对方的 MAC 地址。
        • 交换机:同一局域网内,主机和主机通过交换机进行通信【因为交换机位于网络模型的第二层链路层,所以又叫2层设备,也叫二层交换机】。在MAC层,交换机用来将网络包原样转发到目的地【发送了包之后目标设备会作出响应,只要返回了响应包,交换机就可以将它的地址写入 MAC 地址表,下次也就不需要把包发到所有端口了。所以此处的广播不会造成网络堵塞
          在这里插入图片描述
          • 交换机中记录维护了一个MAC地址列表,这个列表中记录了LAN口和MAC地址的对应关系,如果两台主机通信时,如果目标主机的MAC地址在交换机的MAC列表中,交换机直接通过列表转发给该MAC地址对应的LAN端口;如果目标MAC地址不在列表中,就通过广播的形式对交换机上所有的LAN端口进行转发。
            java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第80张图片
        • 路由器是基于 IP 设计的,俗称三层网络设备,路由器的各个端口都具有 MAC 地址和 IP 地址;而交换机是基于以太网设计的,俗称二层网络设备,交换机的端口不具有 MAC 地址
      • 物理层:实现相邻节点间比特流的透明传输,尽可能屏蔽传输介质和通信手段的差异。
        • 当数据准备要从设备发送到⽹络的时候,需要把数据包转换成电信号,让其可以在物理介质中传输,它主要是为数据链路层提供⼆进制传输的服务
        • 网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。最后网卡会将包转为电信号,通过网线发送出去。
          java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第81张图片
        • 再包括其他的一些概念:广城局域网、网卡分有无线、网卡作用是调制解调、传输介质分类:导向式【网线、电缆、光纤】和非导向式【蓝牙、红外、WIFI、量子、微波】、传输介质之网线的分类的构成:双绞线和水晶头
          • 网卡的协商机制:自适应网卡(1000Mbps、100Mbps),协商机制、兼容性、向下兼容
          • 网卡工作模式:单工、半双工、双工
        • 网卡有两个地址:
          • 物理地址:又叫MAC地址每一个厂商的每一块网卡都有,全球唯一。window中输入ipconfig /all,通常不可变。比如DC-4A-3E-E6-B9-2D:6组16进制数的方式表示
          • 逻辑地址:又叫IP地址【IP协议提供的一种统一的地址格式,用来标识网络中的主机,为互联网上每一个网络和主机都分配一个逻辑地址】,通常可变。包含IPV4【4组十进制组成】和IPV6。因为MAC地址确实不好记忆,所以搞了一个好记的IP地址出来。更多的IP地址见上面网络层内的IP相关
            • IPV6主要作用是提高安全性、身份认证、隐私权、增大地址空间

互联网的本质就是一堆协议。程序员嫌OSI七层太麻烦了,所以把模型优化或者说简化为四层或者五层

  • TCP/IP四层模型TCP/IP其实就是由一些小的子网(子网相当于用集线器连接起来的几台计算机)通过路由器连接起来组成一个大的网络,四层模型比较常见和实用
    • 是由实际应用发展总结出来的,从实质上讲,TCP/IP只有最上面三层,最下面一层没有什么具体内容,TCP/IP参考模型没有真正描述这一层的实现。
    • OSI 七层模型当时一直被一些大公司甚至一些国家政府支持,但是由于以下几个原因,还是没有广泛被使用:
      • OSI 的专家缺乏实际经验,他们在完成 OSI 标准时缺乏商业驱动力
      • OSI 的协议实现起来过分复杂,而且运行效率很低
      • OSI 制定标准的周期太长,因而使得按 OSI 标准生产的设备无法及时进入市场(20 世纪 90 年代初期,虽然整套的 OSI 国际标准都已经制定出来,但基于 TCP/IP 的互联网已经抢先在全球相当大的范围成功运行了
      • OSI 的层次划分不太合理,有些功能在多个层次中重复出现
  • 五层模型
    • 五层模型只出现在计算机网络教学过程中,这是对七层模型和四层模型的一个折中,既简洁又能将概念阐述清楚。
      java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第82张图片
    • 每一层的封装格式:
      java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第83张图片
    • 网络接口层(Network interface layer):可以把网络接口层看作是数据链路层和物理层的合体。
      java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-1(计算机网络体系_七层模型&五层模型&TCP/IP四层模型、TCP&UDP&IP的故事【TCP三握四挥】)整起_第84张图片

巨人的肩膀:
网络是怎样连接的
深入理解计算机网络
小林coding
javaGuide
腾讯云社区企鹅号 - PHP开源社区的老师的文章,关于应用系统之间数据传输的四种方式:应用系统之间数据传输有三个要素:传输方式【数据传输方式一般无非是:socket方式、ftp/文件共享服务器方式、数据库共享数据方式、message方式】,传输协议,数据格式
P妞酱儿老师关于应用系统间数据传输方式总结

你可能感兴趣的:(唠计网,唠OS,唠计组,唠数算,java,tcp/ip,udp,网络模型,应用层)