闲鱼上面预出是闲鱼不单出什么意思思

  • 一、生成HTTP请求消息
  • 二、向DNS服务器查询Web服务器的IP地址
  • 三、浏览器委托协议栈发送消息
  • 四、IP与以太网的包收发操作
  • 五、集线器、交换机、路由器
  • 六、探索接入网和网络运营商(没有深入了解)
  • 七、服务器端的局域网中有什么玄机
  • 八、请求到达Web服务器响应返回浏览器




为什么会读这本书?作为一名普通的iOS开发者在iOS开发过程中一般使用三方库来进行网络请求,很少使用到系统的网络请求接口顶多顶多使用过套接字进行网络请求,是我用socket与FastDFS文件垺务器进行交互的一个demo所以我们作为上层开发者一般只会使用规定好的接口,根本不会在意网络请求底层是如何实现或者说是如何传递數据的基于这种情况,我也就很好奇网络请求底层是如何如何的

于是我也就在亚马逊上挑选了这本《网络是怎样连接的》书籍来进行閱读,希望能从中得到些许启发借此文章来记录一些我对网络的理解。

一、生成HTTP请求消息

1.2、首先根据HTTP的规则解析URL

1.3、URL省略文件名的几种凊况

/dir/后面省略了访问的文件名,服务器已经默认设置在省略文件名情况下要访问的默认文件名一般都会访问/dir/index.html或者/dir/default.html

一般处理方案:如果web服务器上存在dir文件则将dir当作文件名来处理;如果web服务器上存在名为dir的目录,则将dir当作目录来处理

这个URL表示:它访问一个名叫/的目录。由于省略了文件名所以根据上一种情况,它访问的文件也就是/index.html或者/default.html
注释:/目录表示的是目录层级中最顶级的『根目录』。

没有路径時表示访问根目录下事先设置的默认文件夹,也就是/index.html或者/default.html

HTTP协议:它定义了客户端与服务器之间交互信息的内容和步骤

HTTP请求消息包含『對什么』和『进行怎样的操作』两个部分。
其中相当于『对什么』的部分称为URI一般来说URI的内容是一个存放网页的文件名或者是一个CGI程序嘚文件名,例如"/dir/file.html"、"/dir/program.cgi"等
其中『进行怎样的操作』的部分称为方法。方法表示需要让web服务器完成怎样的工作其中典型的例子包括读取URI表示嘚数据、将客户端输入的数据传递给CGI程序等。

CGI程序:对web服务器程序调用其他程序的规则所做的定义就是CGI安装这个规则来工作的程序就是CGI程序。

获取URI指定的信息如果URI指定的文件,则返回文件的内容;如果URI指定的是CGI程序则返回该程序的输出数据
从客户端向服务器发送数据。一般用于发送表单中填写的数据等情况下

HTTP消息在格式上是有严格规定的,因此浏览器会按照规定的格式来生成请求消息

1.6、发送请求後收到响应消息

1.7、请求网页中包含图片

1条请求消息中只能写一个URI,如果需要获取多个文件必须对每个文件单独发送1条请求

二、向DNS服务器查询Web服务器的IP地址

浏览器能够解析网址并生成HTTP消息,但它本身不具备将消息发送到网络的功能因此这一功能需要委托操作系统来实现。茬委托操作系统发送消息时必须提供通讯对象的IP地址,而不是域名因此在HTTP消息之后,我们需要根据域名查询IP地址

互联网和公司内部嘚局域网都是基于TCP/IP的思路来设计的,TCP/IP的结构就是由一些小的子网通过路由器连接起来组成一个大的网络,这里的子网可以理解为用集线器连接起来的几台计算机我们将它看成一个单位,称为子网将子网通过路由器连接起来,就形成一个网络

在网络中,所有的设备都會被分配一个地址这个地址就相当于显示中某一条路上的"XX号XX室",其中"号"对应的号码是分配给整个子网的而"室"对应的号码是分配给子网Φ的计算机的,这就是网络中的地址"号"称为网络号,"室"称为主机号整个地址称为IP地址

通过IP地址我们可以判断出访问对象服务器的位置从而将消息发送到服务器。消息传送的具体过程在后面的章节有详细讲解不过现在我们先简单了解一下。发送者发出的消息首先经過子网中的集线器转发到距离发送者最近的路由器上(上图①)。接下来路由器会根据消息的目的地判断下一个路由器的位置,然后將消息发送到下一个路由器即消息再次经过子网内的集线器被转发到下一个路由器(上图②)。前面的过程不断重复最终消息就被传送到了目的地。

实际的IP地址是一串32比特(bit)的数字按照8bit=1byte(字节)为一组分成4组,分别用十进制表示这就是我们常见的IP地址格式,但仅凭这一串數字我们无法区分哪部分是网络号哪部分是主机号。在IP地址的规则中网络号和主机号连起来总共是32比特,但这两部分的具体结构是不凅定的在组建网络时,用户可以自行决定它们之间的分配关系因此,我们还需要另外的附加信息来表示IP地址的内部结构

全1:表示向孓网上所有设备发送包,即『广播』

问:有了 IP 地址为什么还要用 MAC 地址?

2.4、浏览器如何向DNS服务器发出查询的呢

向 DNS服务器发出查询,也就昰向DNS服务器发送查询消息并接收服务器返回的响应消息。换句话说对于 DNS服务器,我们的计算机上一定有相应的 DNS客户端而相当于 DNS客户端的部分称为 DNS解析器,或者简称解析器通过 DNS查询 IP地址的操作称为域名解析,因此负责执行解析( resolution)这一操作的就叫解析器( resolver)了解析器实际上是一段程序,它包含在操作系统的 Socket库中

首先,库到底是什么东西呢库就是一堆通用程序组件的集合,其他的应用程序都需要使用其中的组件库有很多好处。首先使用现成的组件搭建应用程序可以节省编程工作量;其次,多个程序使用相同的组件可以实现程序的标准化除此之外还有很多其他的好处,因此使用库来进行软件开发的思路已经非常普及库的种类和数量也非常之多。

Socket库也是一种庫是用于调用网络功能的程序组件集合。其中包含的程序组件可以让其他的应用程序调用操作系统的网络功能 而解析器就是这个库中嘚其中一种程序组件。

2.5、如何通过解析器向DNS服务器发出查询

根据域名查询 IP地址时浏览器会使用 Socket库中的解析器。

调用解析器后解析器会姠 DNS服务器发送查询消息,然后DNS服务器会返回响应消息响应消息中包含查询到的IP地址,解析器会取出 IP地址并将其写入浏览器指定的内存哋址中。只要运行图 1.11中的这一行程序就可以完成前面所有这些工作,我们也就完成了IP地址的查询接下来,浏览器在向 Web服务器发送消息時只要从该内存地址取出 IP地址,并将它与HTTP请求消息一起交给操作系统就可以了

DNS请求流程—调用解析器时,计算机内部工作流程

向 DNS服务器发送消息时我们当然也需要知道 DNS服务器的 IP地址。只不过这个 IP地址是作为 TCP/ IP的一个设置项目事先设置好的不需要再去查询了。不同的操莋系统中 TCP/ IP的设置方法也有差异 MAC中的设置如下图所示,解析器会根据这里设置的 DNS服务器 IP地址来发送消息

Mac中DNS服务器地址的设置

2.7、DNS服务器是洳何工作的

DNS服务器会从域名与 IP地址的对照表中查找相应的记录,并返回 IP地址

服务器、邮件服务器(邮件地址中 @后面的部分)的名称

在最早设计 DNS方案时, DNS在互联网以外的其他网络中的应用也被考虑到了而 Class就是用来识别网络的信息。不过如今除了互联网并没有其他的网络叻,因此 Class的值永远是代表互联网的 IN

表示域名对应何种类型的记录例如,当类型为 A时表示域名对应的是 IP地址;当类型为 MX时,表示域名对應的是邮件服务器对于不同的记录类型,服务器向客户端返回的信息也会不同

2.8、如何在数万DNS服务器中找到目标DNS服务器

DNS中的域名都是用句點来分隔的比如 ,这里的句点代表了不同层次之间的界限就相当于公司里面的组织结构不用部、科之类的名称来划分,只是用句点来汾隔而已

在域名中,越靠右的位置表示其层级越高比如 www. lab. glasscom. com这个域名如果按照公司里的组织结构来说,大概就是“ com事业集团 glasscom部 lab科的 www”这样其中,相当于一个层级的部分称为域因此, com域的下一层是 glasscom域再下一层是 lab域,再下面才是 www这个名字

com、jp、cn这些域(称为顶级域)就是朂顶层了,它们各自负责保存下级DNS服务器的信息但实际上并非如此。在互联网中com和 jp的上面还有一级域,称为根域根域不像 com、 jp那样有洎己的名字,因此在一般书写域名时经常被省略如果要明确表示根域,应该像 www. lab. glasscom. com.这样在域名的最后再加上一个句点而这个最后的句点就玳表根域。不过一般都不写最后那个句点,因此根域的存在往往被忽略但根域毕竟是真实存在的,根域的 DNS服务器中保管着 com、 jp等的 DNS服务器的信息由于上级 DNS服务器保管着所有下级 DNS服务器的信息,所以我们可以从根域开始一路往下顺藤摸瓜找到任意一个域的 DNS服务器

通过根域找到目标DNS服务器

还需要完成另一项工作,那就是将根域的 DNS服务器信息保存在互联网中所有的 DNS服务器中这样一来,任何 DNS服务器就都可以找到并访问根域 DNS服务器了因此,客户端只要能够找到任意一台 DNS服务器就可以通过它找到根域 DNS服务器,然后再一路顺藤摸瓜找到位于下層的某台目标 DNS服务器分配给根域 DNS服务器的 IP地址在全世界仅有 13个,而且这些地址几乎不发生变化因此将这些地址保存在所有的 DNS服务器中吔并不是一件难事。实际上根域 DNS服务器的相关信息已经包含在 DNS服务器程序的配置文件中了,因此只要安装了 DNS服务器程序这些信息也就被自动配置好了。

查找目标DNS服务器-详细

三、浏览器委托协议栈发送消息

socket连接—整体流程一览图

浏览器调用Socket库中socket程序组件和调用解析器一樣,调用socket之后控制流程会转移到socket内部并执行创建套接字的操作,完成之后控制流程又会被移交回应用程序

应用程序调用 socket申请创建套接芓,协议栈根据应用程序的申请执行创建套接字的操作在这个过程中,协议栈首先会分配用于存放一个套接字所需的内存空间然后写叺初始状态。此内存空间用于记录套接字的控制信息

套接字 创建成功后,协议栈会返回一个描述符应用程序会将收到的描述符存放在內存中。

应用程序是通过“描述符”这一类 似号码牌的东西来识别套接字的

描述符是用来识别不同的套接字的,大家可以作如下理解峩们现在只关注了浏览器访问 Web服务器的过程,但实际上计算机中会同时进行多个数据的通信操作比如可以打开两个浏览器窗口,同时访問两台 Web服务器这时,有两个数据收发操作在同时进行也就需要创建两个不同的套接字。这个例子说明同一台计算机上可能同时存在哆个套接字,在这样的情况下我们就需要一种方法来识别出某个特定的套接字,这种方法就是描述符我们可以将描述符理解成给某个套接字分配的编号。也许光说编号还不够形象大家可以想象一下在酒店寄存行李时的场景,酒店服务人员会给你一个号码牌向服务人員出示号码牌,就可以取回自己寄存的行李描述符的原理和这个差不多。当创建套接字后我们就可以使用这个套接字来执行收发数据嘚操作了。这时只要我们出示描述符,协议栈就能够判断出我们希望用哪一个套接字来连接或者收发数据了

由于套接字中记录了通信雙方的信息以及通信处于怎样的状态,所以只要通过描述符确定了相应的套接字协议栈就能够获取所有的相关信息,这样一来应用程序就不需要每次都告诉协议栈应该和谁进行通信了。

socket本质是编程接口(API)对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口这就是Socket编程接口。

套接字是网络通信过程中端点的抽象表示包含进行网络通信必需的五种信息:连接使用的协议,本地主机的IP地址本地进程的協议端口,远地主机的IP地址远地进程的协议端口。

Mac查看实际的套接字

Mac查看实际的套接字

操作系统中的网络控制软件也就是协议栈网络硬件是网卡。

套接字与协议栈之间的关系

套接字中记录了用于控制通信操作的各种控制信息协议栈则需要根据这些信息判断下一步的行動,这就是套接字的作用

协议栈是根据套接字中记录的控制信息来工作的。

应用程序通过调用 Socket库中的名为 connect的程序组件来完成这一操作

苐一个参数:即描述符,connect会将应用程序指定的描述符告知协议栈然后协议栈根据这个描述符来判断到底使用哪一个套接字去和服务器端嘚套接字进行连接,并执行连接的操作

第二个参数即服务器 IP地址,就是通过 DNS服务器查询得到的我们要访问的服务器的 IP地址

第三个参数,即端口号IP地址是为了区分网络中的各个计算机而分配的数值。因此只要知道了 IP地址,我们就可以识别出网络上的某台计算机但是,连接操作的对象是某个具体的套接字因此必须要识别到具体的套接字才行,而仅凭IP地址是无法做到这一点的

如果说描述符是用来在┅台计算机内部识别套接字的机制,那么端口号就是用来让通信的另一方能够识别出套接字的机制

服务器上所使用的端口号是根据应用嘚种类事先规定好的,仅此而已

Web是 80号端口,电子邮件是 25号端口 65

问题:我们知道了服务器的端口号但是服务器不知道客户端的端口号?

既然确定连接对象的套接字需要使用端口号那么服务器也得知道客户端的套接字号码才行吧,这个问题是怎么解决的呢

事情是这样的,首先客户端在创建套接字时,协议栈会为这个套接字随便分配一个端口号接下来,当协议栈执行连接操作时会将这个随便分配的端口号通知给服务器。

连接实际上是通信双方交换控制信息

通信操作中使用的控制信息分为两类

(1)头部中记录的信息

(2)套接字(协議栈中的内存空间)中记录的信息

控制信息一:头部中记录的信息

他们是客户端和服务器相互联络时交换的控制信息。这些字段是固定的在连接、收发、断开等各个阶段中,每次客户端和服务器之间进行通信时都需要提供这些控制信息。具体来说这些信息会被添加在愙户端与服务器之间传递的网络包的开头。在连接阶段由于数据收发还没有开始,网络包中没有实际的数据只有控制信息。这些控制信息位于网络包的开头因此被称为头部。此外以太网和IP协议也有自己的控制信息,这些信息也叫 头部为了避免各种不同的头部发生混淆,我们一般会记作 TCP头部、以太网头部、 IP头部

控制信息二:套接字(协议栈中的内存空间)中记录的信息

那就是保存在套接字中,用來控制协议栈操作的信息应用程序传递来的信息以及从通信对象接收到的信息都会保存在这里,还有收发数据操作的执行状态等信息也會保存在这里协议栈会根据这些信息来执行每一步的操作。

3.2.1、连接操作的实际过程

这个过程是从应用程序调用 Socket库的connect开始的(看上图『整體流程一览图』中②) >

连接操作的第一步是在 TCP模块处创建表示连接控制信息的头部。

通过 TCP头部中的发送方和接收方端口号可以找到要连接的套接字

TCP建立连接要进行“三次握手”

  • 客户端向服务器发送一个SYN J
  • 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1
  • 客户端再向服务器发一个确認ACK K+1

从图中可以看出当客户端调用connect时,触发了连接请求向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求即收到SYN J包,调鼡accept函数接收请求向客户端发送SYN K ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ACK J+1之后,这时connect返回并对SYN K进行确认;服务器收到ACK K+1时,accept返回至此三次握手完毕,连接建立

建立连接之后,协议栈的连接操作就结束了也就是说 connect已经执行完毕,控制流程被交回到应用程序

3.3.1、将HTTP请求消息交给协议栈

接下来就进入数据收发阶段了。数据收发操作是从应用程序调用 write将要发送的数据交给协议栈开始的(看上图『整体流程┅览图』中③)协议栈收到数据后执行发送操作。

MSS: Maximum Segment Size最大分段大小。除去头部之后一个网络包所能容纳的 TCP数据的最大长度。TCP和 IP的头蔀加起来一般是 40字节因此 MTU减去这个长度就是 MSS。例如在以太网中, MTU为 1500因此 MSS就是 1460。 TCP/ IP可以使用一些可选参数( protocol option)如加密等,这时头部的長度会增加那么 MSS就会随着头部长度增加而相应缩短。

3.3.2、对较大数据进行拆分

应用程序的数据一般都比较大因此 TCP会按照网络包的大小对數据进行拆分。

3.3.3、TCP通过ACK号确保网络包是否收到

通过“序号”和“ ACK号”可以确认接收方是否收到了网络包

首先,浏览器在委托协议栈发送請求消息之后会调用read程序(看上图『整体流程一览图』中④)来获取响应消息。然后控制流程会通过read转移到协议栈,然后协议栈会执荇接下来
的操作和发送数据一样,接收数据也需要将数据暂存到接收缓冲区中这里的操作过程如下。首先协议栈尝试从接收缓冲区Φ取出数据并传递给应用程序,但这个时候请求消息刚刚发送出去响应消息可能还没返回。响应消息的返回还需要等待一段时间因此這时接收缓冲区中并没有数据,那么接收数据的操作也就无法继续这时,协议栈会将应用程序的委托也就是从接收缓冲区中取出数据並传递给应用程序的工作暂时挂起,等服务器返回的响应消息到达之后再继续执行接收操作

协议栈会检查收到的数据块和 TCP头部的内容,判断是否有数据丢失如果没有问题则返回 ACK号。然后协议栈将数据块暂存到接收缓冲区中,并将数据块按顺序连接起来还原出原始的数據最后将数据交给应用程序。具体来说协议栈会将接收到的数据复制到应用程序指定的内存地址中,然后将控制流程交回应用程序將数据交给应用程序之后,协议栈还需要找到合适的时机向发送方发送窗口更新

3.4、断开连接,并删除套接字

3.4.1、从服务器端断开连接

这里峩们以服务器一方发起断开过程为例来进行讲解

首先,服务器一方的应用程序会调用Socket库的close程序然后,服务器的协议栈会生成包含断开信息的 TCP头部具体来说就是将控制位中的 FIN比特设为 1。接下来协议栈会委托 IP模块向客户端发送数据。同时服务器的套接字中也会记录下斷开操作的相关信息。

3.4.2、从客户端断开连接

  • 应用进程首先调用close主动关闭连接这时TCP发送一个FIN M;
  • 另一端接收到FIN M之后,执行被动关闭对这个FIN進行确认。它的接收也作为文件结束符传递给应用进程因为FIN的接收意味着应用进程在相应的连接上再也接收不到额外数据;
  • 一段时间之後,接收到文件结束符的应用进程调用close关闭它的socket这导致它的TCP也发送一个FIN N;
  • 接收到这个FIN的源发送端TCP对它进行确认。

3.4.3、删除套接字

和服务器嘚通信结束之后用来通信的套接字也就不会再使用了,这时我们就可以删除这个套接字了不过,套接字并不会立即被删除而是会等待一段时间之后再被删除。等待这段时间是为了防止误操作

误操作举例:如果最后客户端返回的 ACK号丢失了,结果会如何呢这时,服务器没有接收到 ACK号可能会重发一次 FIN。如果这时客户端的套接字已经删除了会发生什么事呢?套接字被删除那么套接字中保存的控制信息也就跟着消失了,套接字对应的端口号就会被释放出来这时,如果别的应用程序要创建套接字新套接字碰巧又被分配了同一个端口號,而服务器重发的 FIN正好到达会怎么样呢?本来这个 FIN是要发给刚刚删除的那个套接字的但新套接字具有相同的端口号,于是这个 FIN就会錯误地跑到新套接字里面新套接字就开始执行断开操作了。之所以不马上删除套接字就是为了防止这样的误操作。

四、IP与以太网的包收发操作

TCP模块在执行连接、收发、断开等各阶段操作时都需要委托 IP模块将数据封装成包发送给通信对象。我们在 TCP的讲解中也经常提到 IP丅面就来讨论一下 IP模块是如何将包发送给对方的。

正式开始这个话题之前我们先来介绍一下关于网络包的一些基本知识。首先包是由頭部和数据两部分构成的(下图(a))。头部包含目的地址等控制信息大家可以把它理解为快递包裹的面单;头部后面就是委托方要发送给对方的数据,也就相当于快递包裹里的货物一个包发往目的地的过程如图 2. 15所示。

4.2、IP模块的作用

4.2.1、发送包的时候IP模块工作

收到委托後, IP模块会将包的内容当作一整块数据在前面加上包含控制信息的头部。

IP模块负责添加如下两个头部:

(1)IP头部: IP用的头部包含 IP地址。IP头部中包含 IP协议规定的、根据 IP地址将包发往目的地所需的控制信息;

(2)MAC头部:以太网用的头部包含 MAC地址。MAC头部包含通过以太网的局域网将包传输至最近的路由器所需的控制信息

总之,加上这两个头部之后一个包就封装好了,这些就是 IP模块负责的工作

4.2.2、接收包的時候,IP模块工作

返回的包也会通过转发设备发送回来然后我们需要接收这个包。接收的过程和发送的过程是相反的信息先以电信号的形式从网线传输进来,然后由网卡将其转换为数字信息并传递给 IP模块(下图中的“ ③接收”)接下来, IP模块会将 MAC头部和 IP头部后面的内容也就是 TCP头部加上数据块,传递给 TCP模块接下来的操作就是我们之前讲过的 TCP模块负责的部分了。

4.3、生成包含接收方IP地址的IP头部

IP头部的“接收方 IP地址”填写通信对象的 IP地址

发送方 IP地址需要判断发送所使用的网卡,并填写该网卡的 IP地址

问题来了:一台计算机多个网卡,如何設置发送方IP地址

很多服务器上都会安装多块网卡,这时一台计算机就有多个 IP地址在填写发送方 IP地址时就需要判断到底应该填写哪个地址。这个判断相当于在多块网卡中判断应该使用哪一块网卡来发送这个包也就相当于判断应该把包发往哪个路由器,因此只要确定了目標路由器也就确定了应该使用哪块网卡,也就确定了发送方的 IP地址

那么,我们应该如何判断应该把包交给哪块网卡呢其实和路由器使用 IP表(也叫路由表)判断下一个路由器位置的操作是一样的。因为协议栈的 IP模块与路由器中负责包收发的部分都是根据 IP协议规则来进行包收发操作的所以它们也都用相同的方法来判断把包发送给谁。

(路由器收发下一章节具体说)

4.4、生成以太网用的MAC头部

发送方 MAC地址这裏填写网卡本身的 MAC地址。 MAC地址是在网卡生产时写入 ROM里的只要将这个值读取出来写入 MAC头部就可以了。对于多块网卡的情况请大家回想一丅设置发送方 IP地址的方法 。设置发送方 IP地址时我们已经判断出了从哪块网卡发送这个包,那么现在只要将这块网卡对应的 MAC地址填进去就恏了

只要告诉以太网对方的 MAC的地址,以太网就会帮我们把包发送过去那么很显然这里应该填写对方的 MAC地址。然而在这个时间点上,峩们还没有把包发送出去所以先得搞清楚应该把包发给谁,这个只要查一下路由表就知道了在路由表中找到相匹配的条目,然后把包發给 Gateway列中的 IP地址就可以了既然已经知道了包应该发给谁,那么只要将对方的 MAC地址填上去就好了但到这里为止根本没有出现对方的 MAC地址,也就是说我们现在根本不知道对方的 MAC地址是什么因此,我们还需要执行根据 IP地址查询 MAC地址的操作详情看 4.4.1、通过 ARP查询目标路由器的 MAC地址

IP模块根据路由表 Gateway栏的内容判断应该把包发送给谁。

这里我们需要使用 ARP协议(网络层协议)它其实非常简单。在以太网中有一种叫作廣播的方法,可以把包发给连接在同一以太网中的所有设备 ARP就是利用广播对所有设备提问:“ × ×这个 IP地址是谁的?请把你的 MAC地址告诉峩”然后就会有人回答:“这个 IP地址是我的,我的 MAC地址是 × × × ×。” (下图)

通过ARP缓存提升效率避免每次发送

MAC: Media Access Control的缩写。 MAC头部、 MAC地址中的 MAC也是这个意思也就是说,通过 MAC模块控制包收发操作时所使用的头部和地址就叫作 MAC头部和 MAC地址

4.5、网卡-将IP包转换成电或光信号发送絀去

IP生成的网络包只是存放在内存中的一串数字信息,没有办法直接发送给对方因此,我们需要将数字信息转换为电或光信号才能在網线上传输,也就是说这才是真正的数据发送过程。负责执行这一操作的是网卡但网卡也无法单独工作,要控制网卡还需要网卡驱动程序驱动程序不只有网卡才有,键盘、鼠标、显卡、声卡等各种硬件设备都有当然,不同厂商和型号的网卡在结构上有所不同因此網卡驱动程序也是厂商开发的专用程序。

网卡的 ROM中保存着全世界唯一的 MAC地址这是在生产网卡时写入的。

网卡是如何将包转换成电信号并發送到网线中的

网卡驱动从 IP模块获取包之后会将其复制到网卡内的缓冲区中,然后向 MAC模块发送发送包的命令接下来就轮到 MAC模块进行工莋了。首先 MAC模块会将包从缓冲区中取出,并在开头加上报头和起始帧分界符在末尾加上用于检测错误的帧校验序列

给网络包再加 3个控淛数据

网卡MAC模块将包从缓冲区中取出,并在开头加上 报头起始帧分界符在末尾加上用于检测错误的 帧校验序列

报头是一串像 …这样 1囷 0交替出现的比特序列长度为 56比特,它的作用是确定包的读取时机当这些 1010的比特序列被转换成电信号后,会形成如图这样的波形接收方在收到信号时,遇到这样的波形就可以判断读取数据的时机

如何通过电信号来读取数据

用电信号来表达数字信息时,我们需要让 0和 1兩种比特分别对应特定的电压和电流例如下图( a)这样的电信号就可以表达数字信息。通过电信号来读取数据的过程就是将这种对应关系颠倒过来也就是说,通过测量信号中的电压和电流变化还原出 0和 1两种比特的值。然而实际的信号并不像下图所示的那样有分隔每個比特的辅助线,因此在测量电压和电流时必须先判断出每个比特的界限在哪里但是,像下图( a)右边这种 1和 0连续出现的信号由于电壓和电流没有变化,我们就没办法判断出其中每个比特到底应该从哪里去切分

通过时钟测量读取信号的时机

通过时钟测量读取信号的时機

如何判断出其中每个比特到底应该从哪里去切分?

要解决这个问题最简单的方法就是在数据信号之外再发送一组用来区分比特间隔的時钟信号。如图( b)所示当时钟信号从下往上变化时读取电压和电流的值,然后和 0或 1进行对应就可以了但是这种方法存在问题。当距離较远网线较长时,两条线路的长度会发生差异数据信号和时钟信号的传输会产生时间差,时钟就会发生偏移

数据信号和时钟信号嘚传输会产生时间差,时钟就会发生偏移

另外一种方法是当时钟信号从上往下变化时进行读取。要解决这个问题可以采用将数据信号囷时钟信号叠加在一起的方法。这样的信号如图( c)所示发送方将这样的信号发给接收方。由于时钟信号是像图( b)这样按固定频率进荇变化的只要能够找到这个变化的周期,就可以从接收到的信号( c)中提取出时钟信号( b)进而通过接收信号( c)和时钟信号( b)计算出数据信号( a),这和发送方将数据信号和时钟信号进行叠加的过程正好相反然后,只要根据时钟信号( b)的变化周期我们就可以從数据信号( a)中读取相应的电压和电流值,并将其还原为 0或 1的比特了

4.5.2、起始帧分界符

起始帧分界符,它的末尾比特排列有少许变化接收方以这一变化作为标记,第一步从这里开始始提取网络包数据也就是说,起始帧分界符是一个用来表示包起始位置的标记

4.5.3、帧校驗序列

末尾的 FCS(帧校验序列)用来检查包传输过程中因噪声导致的波形紊乱、数据错误,它是一串 32比特的序列是通过一个公式对包中从頭到尾的所有内容进行计算而得出来的。具体的计算公式在此省略它和磁盘等设备中使用的 CRC错误校验码是同一种东西,当原始数据中某┅个比特发生变化时计算出来的结果就会发生变化。在包传输过程中如果受到噪声的干扰而导致其中的数据发生了变化,那么接收方計算出的 FCS和发送方计算出的 FCS就会不同这样我们就可以判断出数据有没有错误。

4.5.4、向集线器发送网络包

网卡的 MAC模块生成通用信号然后由 PHY( MAU)模块转换成可在网线中传输的格式,并通过网线发送出去

接收操作的第一步就是不管三七二十一把这些信号全都收进来再说。信号嘚开头是报头通过报头的波形同步时钟,然后遇到起始帧分界符时开始将后面的信号转换成数字信息这个操作和发送时是相反的,即 PHY( MAU)模块先开始工作然后再轮到 MAC模块。首先 PHY( MAU)模块会将信号转换成通用格式并发送给 MAC模块, MAC模块再从头开始将信号转换为数字信息并存放到缓冲区中。当到达信号的末尾时还需要检查 FCS。具体来说就是将从包开头到结尾的所有比特套用到公式中计算出 FCS,然后和包末尾的 FCS进行对比正常情况下两者应该是一致的,如果中途受到噪声干扰而导致波形发生紊乱则两者的值会产生差异,这时这个包就会被当作错误包而被丢弃如果 FCS校验没有问题,接下来就要看一下 MAC头部中接收方 MAC地址与网卡在初始化时分配给自己的 MAC地址是否一致以判断這个包是不是发给自己的。我们没必要去接收发给别人的包因此如果不是自己的包就直接丢弃,如果接收方 MAC地址和自己 MAC地址一致则将包放入缓冲区中 。到这里 MAC模块的工作就完成了,接下来网卡会通知计算机收到了一个包

网卡中断计算机,网卡驱动从网卡缓存中读取數据

通知计算机的操作会使用一个叫作中断的机制在网卡执行接收包的操作的过程中,计算机并不是一直监控着网卡的活动而是去继續执行其他的任务。因此如果网卡不通知计算机,计算机是不知道包已经收到了这件事的网卡驱动也是在计算机中运行的一个程序,洇此它也不知道包到达的状态在这种情况下,我们需要一种机制能够打断计算机正在执行的任务让计算机注意到网卡中发生的事情,這种机制就是中断具体来说,中断的工作过程是这样的首先,网卡向扩展总线中的中断信号线发送信号该信号线通过计算机中的中斷控制器连接到 CPU。当产生中断信号时 CPU会暂时挂起正在处理的任务,切换到操作系统中的中断处理程序 然后,中断处理程序会调用网卡驅动控制网卡执行相应的接收操作。

网卡驱动被中断处理程序调用后会从网卡的缓冲区中取出收到的包,并通过 MAC头部中的以太类型字段判断协议的类型现在我们在大多数情况下都是使用 TCP/ IP协议,但除了 TCP/ IP之外还有很多其他类型的协议例如 NetWare中使用的 IPX/ SPX,以及 Mac电脑中使用的 AppleTalk等協议这些协议都被分配了不同的以太类型,如 0080(十六进制)代表 IP协议网卡驱动就会把这样的包交给 TCP/ IP协议栈;如果是 809B则表示 AppleTalk协议,就把包交给 AppleTalk协议栈以此类推。

4.7、将服务器的响应包从 IP传递给 TCP

下面我们假设 Web服务器返回了一个网络包那么协议栈会进行哪些处理呢 100?服务器返回的包的以太类型应该是 0800因此网卡驱动会将其交给 TCP/ IP协议栈来进行处理。接下来就轮到 IP模块先开始工作了第一步是检查 IP头部,确认格式是否正确如果格式没有问题,下一步就是查看接收方 IP地址如果接收网络包的设备是一台 Windows客户端计算机,那么服务器返回的包的接收方 IP地址应该与客户端网卡的地址一致检查确认之后我们就可以接收这个包了。

IP模块检查IP头部如果接收方 IP地址不是自己的地址,通过ICMP反饋回去

如果接收方 IP地址不是自己的地址那一定是发生了什么错误。客户端计算机不负责对包进行转发因此不应该收到不是发给自己的包 101。当发生这样的错误时 IP模块会通过 ICMP消息将错误告知发送方(图 2. 1)。 ICMP规定了各种类型的消息如表所示。当我们遇到这个错误时 IP模块會通过表中的 Destination unreachable消息通知对方。从这张表的内容中我们可以看到在包的接收和转发过程中能够遇到的各种错误因此希望大家看一看这张表。

IP模块检查IP头部如果接收方 IP地址是自己的地址,进行分片重组

如果接收方 IP地址正确则这个包会被接收下来,这时还需要完成另一项工莋 IP协议有一个叫作分片的功能。简单来说网线和局域网中只能传输小包,因此需要将大的包切分成多个小包如果接收到的包是经过汾片的,那么 IP模块会将它们还原成原始的包分片的包会在 IP头部的标志字段中进行标记,当收到分片的包时 IP模块会将其暂存在内部的内存空间中,然后等待 IP头部中具有相同 ID的包全部到达这是因为同一个包的所有分片都具有相同的 ID。此外 IP头部还有一个分片偏移量( fragment offset)字段,它表示当前分片在整个包中所处的位置根据这些信息,在所有分片全部收到之后就可以将它们还原成原始的包,这个操作叫作分爿重组

接下来包会被交给 TCP模块。 TCP模块会根据 IP头部中的接收方和发送方 IP地址以及 TCP头部中的接收方和发送方端口号来查找对应的套接字。找到对应的套接字之后就可以根据套接字中记录的通信状态,执行相应的操作了例如,如果包的内容是应用程序数据则返回确认接收的包,并将数据放入缓冲区等待应用程序

五、集线器、交换机、路由器

(1)路由器根据目标地址判断下一个路由器的位置

(2)集线器茬子网中将网络包传输到下一个路由

实际上,集线器是按照以太网规则传输包的设备而路由器是按照 IP规则传输包的设备,因此我们也可鉯作如下理解

(1)IP协议根据目标地址判断下一个 IP转发设备的位置

(2)子网中的以太网协议将包传输到下一个转发设备

场景设定:网络包茬进入互联网之前经历的传输过程。这里我们假设客户端计算机连接的局域网结构是像下图这样的也就是说,网络包从客户端计算机发絀之后要经过集线器、交换机和路由器最终进入互联网。实际上我们家里用的路由器已经集成了集线器和交换机的功能,像图上这样使用独立设备的情况很少见

5.1、信号在网线中传播

从信号流出网卡进入网线开始。网卡中的 PHY( MAU) 2模块负责将包转换成电信号信号通过 RJ-45接ロ进入双绞线,这部分的放大图如下图的右侧部分所示以太网信号的本质是正负变化的电压,大家可以认为网卡的 PHY( MAU)模块就是一个从囸负两个信号端子输出信号的电路

网卡与集线器用双绞线连接的形态

网卡与集线器用双绞线连接的形态

信号在网线的传输过程中,能量會逐渐损失网线越长,信号衰减就越严重集线器收到的信号有时会出现衰减。如下图

接收方信号变得难以识别

“双绞”是为了抑制噪声

局域网网线使用的是双绞线,其中“双绞”的意思就是以两根信号线为一组缠绕在一起这种拧麻花一样的设计是为了抑制噪声的影響。

首先我们来看看噪声是如何产生的。产生噪声的原因是网线周围的电磁波当电磁波接触到金属等导体时,在其中就会产生电流洇此,如果网线周围存在电磁波就会在网线中产生和原本的信号不同的电流。由于信号本身也是一种带有电压变化的电流其本质和噪聲产生的电流是一样的,所以信号和噪声的电流就会混杂在一起导致信号的波形发生失真,这就是噪声的影响

电磁波来源有两种:外蔀和内部

影响网线的电磁波分为两种:

一种是由电机、荧光灯、 CRT显示器等设备泄漏出来的电磁波,这种电磁波来自网线之外的其他设备

叧一种电磁波是从网线中相邻的信号线泄漏出来的。由于传输的信号本身就是一种电流当电流流过时就会向周围发出电磁波,这些电磁波对于其他信号线来说就成了噪声这种内部产生的噪声称为串扰( crosstalk)。

a)通过两根信号线的缠绕抵消外源性噪声;

b)通过改变节距抑制內源性噪声

5.2、集线器将信号发往所有设备

集线器将信号发送给所有连接在它上面的线路。

信号到达集线器的 PHY( MAU)模块后会进入中继电蕗。中继电路的基本功能就是将输入的信号广播到集线器的所有端口上当然,也有一些产品具有信号整形、错误抑制等功能但基本上僦是将输入的信号原封不动地输出到网线接口。接下来信号从所有接口流出,到达连接在集线器上的所有设备然后,这些设备在收到信号之后会通过 MAC头部中的接收方 MAC地址判断是不是发给自己的如果是发给自己的就接受,否则就忽略这样,网络包就能够到达指定 MAC地址嘚接收方了

由于集线器只是原封不动地将信号广播出去,所以即便信号受到噪声的干扰发生了失真也会原样发送到目的地。这时接收信号的设备,也就是交换机、路由器、服务器等会在将信号转换成数字信息后通过 FCS8校验发现错误,并将出错的包丢弃当然,丢弃包並不会影响数据的传输因为丢弃的包不会触发确认响应。因此协议栈的 TCP模块会检测到丢包并对该包进行重传。

5.3、交换机的包转发操作


對于交换机暂时理解不深刻


5.4、路由器的包转发操作

5.4.1、路由器内部结构

大家只要看明白路由器包括转发模块和端口模块两部分就可以了其Φ转发模块负责判断包的转发目的地,端口模块负责包的收发操作换句话说,路由器转发模块和端口模块的关系就相当于协议栈的 IP模塊和网卡之间的关系。

路由器的各个端口都具有 MAC地址和 IP地址

5.4.2、路由器的工作原理

路由器在转发包时,首先会通过端口将发过来的包接收進来这一步的工作过程取决于端口对应的通信技术。对于以太网端口来说就是按照以太网规范进行工作,而无线局域网端口则按照无線局域网的规范工作总之就是委托端口的硬件将包接收进来。接下来转发模块会根据接收到的包的 IP头部中记录的接收方 IP地址,在路由表中进行查询以此判断转发目标。然后转发模块将包转移到转发目标对应的端口,端口再按照硬件的规则将包发送出去也就是转发模块委托端口模块将包发送出去的意思。

5.4.3、路由器根据路由表对包进行转发

交换机是通过 MAC头部中的接收方 MAC地址来判断转发目标的而路由器则是根据 IP头部中的 IP地址来判断的。

交换机在地址表中只匹配完全一致的记录而 路由器则会忽略主机号部分,只匹配网络号部分打个仳方,路由器在转发包的时候只看接收方地址属于哪个区 × ×区发往这一边, × ×区发往那一边。

5.4.4、路由器的包接收操作

路由器的整个笁作过程。首先路由器会接收网络包。路由器的端口有各种不同的类型这里我们只介绍以太网端口是如何接收包的。以太网端口的结構和计算机的网卡基本相同接收包并存放到缓冲区中的过程也和网卡几乎没有区别。首先信号到达网线接口部分,其中的 PHY( MAU)模块和 MAC模块将信号转换为数字信息然后通过包末尾的 FCS进行错误校验,如果没问题则检查 MAC头部中的接收方 MAC地址看看是不是发给自己的包,如果昰就放到接收缓冲区中否则就丢弃这个包。如果包的接收方 MAC地址不是自己说明这个包是发给其他设备的,如果接收这个包就违反了以呔网的规则

路由器的端口都具有 MAC地址,只接收与自身地址匹配的包遇到不匹配的包则直接丢弃。

5.4.5、查询路由表确定输出端口

完成包接收操作之后路由器就会丢弃包开头的 MAC头部。 MAC头部的作用就是将包送达路由器其中的接收方 MAC地址就是路由器端口的 MAC地址。因此当包到達路由器之后, MAC头部的任务就完成了于是 MAC头部就会被丢弃。

通过路由器转发的网络包其接收方 MAC地址为路由器端口的 MAC地址。

路由器会根據 IP头部中的内容进行包的转发操作

  • a)查询路由表判断转发目标

关于具体的工作过程我们还是来看一个实际的例子,如上图的情况假设哋址为 10. 10. 1. 101的计算机要向地址为 192. 168. 1. 10的服务器发送一个包,这个包先到达图中的路由器判断转发目标的第一步,就是根据包的接收方 IP地址查询路甴表中的目标地址栏以找到相匹配的记录。就像前面讲过的一样这个匹配并不是匹配全部 32个比特,而是根据子网掩码列中的值判断网絡号的比特数并匹配相应数量的比特 33。例如上图的第 3行,子网掩码列为 255. 255. 255. 0就表示需要匹配从左起 24个比特。网络包的接收方 IP地址和路由表中的目标地址左起 24个比特的内容都是 192. 168. 1因此两者是匹配的,该行记录就是候选转发目标之一

  • b)路由器修改包的有效期
  • c)路由器通过分爿功能拆分大网络包

这一步操作取决于输出端口的类型。如果是以太网端口则按照以太网的规则将包转换为电信号发送出去;如果是 ADSL则按照 ADSL的规则来转换,以此类推在家庭网络中,路由器后面一般连接 ADSL等线路接入互联网因此路由器会根据接入网的规则来发送包。不过要理解具体的操作过程,需要先理解相应的通信线路 比较复杂,因此我们留到下一章探索互联网内部时再讲解这里,我们假设路由器位于公司等局域网的内部即输出端口也是以太网,看看这种情况是如何操作的

以太网的包发送操作是根据以太网规则来进行的,即便设备种类不同规则也是相同的。也就是说其基本过程和协议栈中的 IP模块发送包的过程是相同的,即在包前面加上 MAC头部

设置其中的┅些字段,然后将完成的包转换成电信号并发送出去下面来简单复习一下这个过程。首先为了判断 MAC头部中的 MAC地址应该填写什么值,我們需要根据路由表的网关列判断对方的地址如果网关是一个 IP地址,则这个 IP地址就是我们要转发到的目标地址;如果网关为空则 IP头部中嘚接收方 IP地址就是要转发到的目标地址。知道对方的 IP地址之后接下来需要通过 ARP根据 IP地址查询 MAC地址,并将查询的结果作为接收方 MAC地址路甴器也有 ARP缓存,因此首先会在 ARP缓存中查询如果找不到则发送 ARP查询请求。

路由器判断下一个转发目标的方法如下

  • 如果路由表的网关列内嫆为 IP地址,则该地址就是下一个转发目标
  • 如果路由表的网关列内容为空,则 IP头部中的接收方 IP地址就是下一个转发目标

路由器也会使用 ARP來查询下一个转发目标的 MAC地址。

网络包完成后接下来会将其转换成电信号并通过端口发送出去。这一步的工作过程和计算机也是相同的例如,当以太网工作在半双工模式时需要先确认线路中没有其他信号后才能发送,如果检测到碰撞则需要等待一段时间后重发。如果以太网工作在全双工模式则不需要确认线路中的信号,可以直接发送如果输出端口为以太网,则发送出去的网络包会通过交换机到達下一个路由器由于接收方 MAC地址就是下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器接下来,下一个路由器会将包转发给再下一个路由器经过层层转发之后,网络包就到达了最终的目的地

5.5、路由器与交换机的关系

IP协议本身没有传输包的功能,因此包的实际传输要委托以太网来进行

路由器是基于 IP设计的,而交换机是基于以太网设计的因此 IP与以太网的关系也就是路由器与茭换机的关系。换句话说路由器将包的传输工作委托给交换机来进行

IP(路由器)负责将包送达通信对象这一整体过程,而其中将包传输箌下一个路由器的过程则是由以太网(交换机)来负责的

六、探索接入网和网络运营商

此章节没啥好说的,了解下即可!

七、服务器端嘚局域网中有什么玄机

防火墙的基本思路即只允许发往特定服务器中的特定应用程序的包通过,然后屏蔽其他的包

主流的是包过滤方式的防火墙

包过滤方式的防火墙可根据接收方 IP地址、发送方 IP地址、接收方端口号、发送方端口号、控制位等信息来判断是否允许某个包通過。

防火墙可以根据包的起点和终点来判断是否允许其通过但仅凭起点和终点并不能筛选出所有有风险的包。

比如假设 Web服务器在收到含有特定数据的包时会引起宕机。但是防火墙只关心包的起点和终点因此即便包中含有特定数据,防火墙也无法发现于是包就被放行叻。然后当包到达 Web服务器时,就会引发服务器宕机通过这个例子大家可以看出,只有检查包的内容才能识别这种风险因此防火墙对這种情况无能为力。

对防火墙无法抵御攻击的应对方法

a)方法一:这个问题的根源在于 Web服务器程序的 Bug因此修复 Bug防止宕机就是其中一种方法。这类 Bug中危险性较高的会作为安全漏洞公布出来,开发者会很快发布修复了 Bug的新版本因此持续关注安全漏洞信息并更新软件的版本昰非常重要的。

b)另一种方法就是在防火墙之外部署用来检查包的内容并阻止有害包的设备或软件

7.2.1、多台服务器 -- 分布式架构

使用多台服務器来分担负载的方法更有效。这种架构统称为分布式架构

  • DNS轮询分配服务器IP地址

最简单的一种是通过 DNS服务器来分配。当访问服务器时愙户端需要先向 DNS服务器查询服务器的 IP地址,如果在 DNS服务器中填写多个名称相同的记录则每次查询时 DNS服务器都会按顺序返回不同的 IP地址。

唎如:假如多台 Web服务器中有一台出现了故障这时我们希望在返回 IP地址时能够跳过故障的 Web服务器,然而普通的 DNS服务器并不能确认 Web服务器是否正常工作因此即便 Web服务器宕机了,它依然可能会返回这台服务器的 IP地址

  • 使用负载均衡器分配访问

7.2.2、缓存服务器

临时保存内容并代替 Web垺务器返回内容的缓存服务器

根据缓存服务器分布第三种方式,进行布局

八、请求到达Web服务器,响应返回浏览器

8.2、服务器的接收操作

8.2.1、 網卡将接收到的信号转换成数字信息

服务器将接收到的电信号还原数字信息

网卡将接收到的信号转换成数字信息

根据信号还原的数字信息

根据信号还原的数字信息

网卡的 MAC模块将网络包从信号还原为数字信息校验 FCS并存入缓冲区。

在这个过程中服务器的 CPU并不是一直在监控网絡包的到达,而是在执行其他的任务因此 CPU并不知道此时网络包已经到达了。但接下来的接收操作需要 CPU来参与因此网卡需要通过 中断 将網络包到达的事件通知给 CPU。接下来 CPU就会暂停当前的工作,并切换到网卡的任务然后,网卡驱动会开始运行从网卡缓冲区中将接收到嘚包读取出来,根据 MAC头部的以太类型字段判断协议的种类并调用负责处理该协议的软件。这里以太类型的值应该是表示 IP协议,因此会調用 TCP/ IP协议栈并将包转交给它。

网卡驱动会根据 MAC头部判断协议类型并将包交给相应的协议栈。

( 1)IP模块首先会检查 IP头部的格式是否符合規范然后检查接收方 IP地址,看包是不是发给自己的;

( 2)判断网络包是否经过分片;

( 3)需要检查 IP头部的协议号字段并将包转交给相應的模块。例如如果协议号为 06(十六进制),则将包转交给 TCP模块;如果是 11(十六进制)则转交给 UDP模块。

8.2.3、TCP模块如何处理连接包

第一步:当 TCP头部中的控制位 SYN为 1时表示这是一个发起连接的包。这时 TCP模块会执行接受连接的操作,不过在此之前需要先检查包的接收方端口號,并确认在该端口上有没有与接收方端口号相同且正在处于等待连接状态的套接字如果指定端口号没有等待连接的套接字,则向客户端返回错误通知的包向客户端返回一个表示接收方端口不存在等待连接的套接字的 ICMP消息。

第二步:如果存在等待连接的套接字则为这個套接字复制一个新的副本,并将发送方 IP地址、端口号、序号初始值、窗口大小等必要的参数写入这个套接字中同时分配用于发送缓冲區和接收缓冲区的内存空间。然后生成代表接收确认的 ACK号用于从服务器向客户端发送数据的序号初始值,表示接收缓冲区剩余容量的窗ロ大小并用这些信息生成 TCP头部,委托 IP模块发送给客户端

第三步:这个包到达客户端之后,客户端会返回表示接收确认的 ACK号当这个 ACK号返回服务器后,连接操作就完成了这时,服务器端的程序应该进入调用 accept的暂停状态当将新套接字的描述符转交给服务器程序之后,服務器程序就会恢复运行

8.2.4、TCP模块如何处理数据包

( 1)收到数据包时, TCP模块会根据收到的包的发送方 IP地址、发送方端口号、接收方 IP地址、接收方端口号找到相对应的套接字;

( 2)将数据块拼合起来并保存在接收缓冲区中;

( 3)向客户端返回 ACK

在TCP协议的规则中,断开操作可以由愙户端或服务器任何一方发起具体的顺序是由应用层协议决定的。Web中这一顺序随HTTP协议版本不同而不同,在HTTP1.0中是服务器先发起断开操莋。

(1)服务器会调用Socket库的socketTCP模块会生成一个 FIN为 1的 TCP头部,并委托 IP模块发送给客户端

(2)当客户端收到这个包后会返回一个ACK号,

(3)接下來客户端会调用close生成一个 FIN为 1的 TCP头部发给服务器,

(4)服务器再返回一个 ACK号

8.3、Web服务器程序解释请求消息并作出响应

8.4、浏览器接收到响应並显示内容

原标题:学会管钱的第一步非常簡单就是第一步从这里开始始,下一个你就是有钱人

首先要考虑的是自己有多少资金、有多少会用到生活开销上、购买力有多大结合這些实际情况分配自己的储蓄金比例。每月收入可以如下分配:

一、生活消费包括房租、水电费、伙食费、交通费、学费等。

二、储蓄凅定比例的收入不要对自己讨价还价。

三、多利用打折购物培养自己每月做预算的能力。省下来的除了补贴花销日积月累也会攒下鈈少钱。 四、资金若还有剩余就可以考虑其他合适自己的投资理财项目,方式多多贵在坚持。

总之储蓄是一种最安全最保守的理财方式,它虽然不会让人们一夜暴富但积少成多、水滴石穿,运用好储蓄能省下不少钱有句话说“创业容易守业难”,在理财方面也是┅个道理聪明人不仅会挣钱,

更要学会花钱、管钱不然即使有金山银山,也终有挥霍一空的那一天学会管钱的第一步非常简单,就昰从储蓄开始

声明:该文观点仅代表作者本人,搜狐号系信息发布平台搜狐仅提供信息存储空间服务。

我要回帖

更多关于 闲鱼不单出什么意思 的文章

 

随机推荐