二. 用电信号传输TCP/IP ----探索协议栈和网卡
本章的内容是探索操作系统中的网络协议栈和网卡是怎样将浏览器的消息发送给服务器的;
协议栈的内部结构为:
- 应用程序:首先就是一些应用程序,他们会将收发数据等工作委派给下层部分来完成;下面是socket库,其中包含解析器、socket、bind、listen、connect等函数;
- 操作系统:也就是协议栈,有两部分:上部分的TCP、UDP是接收应用程序委托,负责收发数据的部分;下部分的IP协议是分包和分组转发的;
- 驱动程序:负责控制网卡硬件;
- 网卡:完成实际的收发操作,也就是对网线中电信号的收发操作;
应用程序通过调用socket库来让协议栈将浏览器的消息发送给服务器的;过程如下:
1.创建套接字
首先是准备阶段。应用程序调用socket申请创建套接字,协议栈首先分配一个套接字所需的内存空间,然后向其中写入初始状态并将表示这个套接字的描述符返回应用程序。
应用程序就可以通过此描述符找到相应的套接字。而套接字中记录了通信双方的信息以及通信处于怎样的状态;
在协议栈内部有一块用于存放控制信息的内存空间,例如通信对象的IP地址、端口号、通信操作的进行状态、超时重传的时间等,协议栈收发数据时会参阅这些信息;本来套接字就只是一个概念而已,并不存在实体,如果一定要赋予它一个实体,我们可以说这些控制信息就是套接字的实体,或者说存放控制信息的内存空间就是套接字的实体。
Windows下可以使用netstat命令显示套接字内容(图中每一行都相当于一个套接字):
2.连接服务器
创建套接字之后,应用程序(浏览器)就会调用connect,随后协议栈会将本地的套接字与服务器的套接字进行连接。
1)什么是连接
连接实际上是通信双方交换控制信息(用于控制数据收发操作所需的信息,比如IP、端口号等),并在套接字中记录这些必要信息并准备数据收发的一连串操作,具体为以下三点:
- 套接字刚刚创建完成的时候,里面并没有存放任何数据,所以协议栈不知道通信的对象是谁。而浏览器可以根据网址来查询服务器的IP地址,而且根据规则也知道应该使用的端口号;所以通过连接的方式将服务器的IP地址和端口号等信息告知协议栈。
- 服务器上也会创建套接字,但服务器上的协议栈也不知道和谁通信。于是,我们需要让客户端向服务器告知必要的信息,比如“我想和你开始通信,我的IP地址是xxx.xxx. xxx.xxx,端口号是yyyy。”可见,客户端向服务器传达开始通信的请求,也是连接操作的目的之一。
- 当执行数据收发操作时,我们还需要一块用来临时存放要收发的数据的内存空间,这块内存空间称为缓冲区,它也是在连接操作的过程中分配的。
2)连接操作的具体过程
也就是三次握手的过程;建立连接之后,协议栈的连接操作就结束了,也就是说connect已经执行完毕,控制流程被交回到应用程序并进入收发阶段。
3.收发数据
应用程序使用Write将要发送的数据交给协议栈,协议栈做如下操作:
- 协议栈先将数据存放到内部的发送缓冲区中,并等待应用程序的下一段数据。因为一次将多少数据交给协议栈是应用程序决定的,如果一收到就发出去会导致发出很多小包,降低网络效率;所以会积累一定量的数据才一次性发出去,至于积累多少则取决于不同种类和版本的操作系统;
判断要素就是数据长度(以太网中网络包不能超过1500字节)和发送时间,如果长度优先,那么网络的效率会提高,但可能会因为等待填满缓冲区而产生延迟;相反地,如果时间优先,那么延迟时间会变少,但又会降低网络的效率。
因此应用程序在发送数据时可以指定一些选项,比如如果指定“不等待填满缓冲区直接发送”,则协议栈就会按照要求直接发送数据。像浏览器这种会话型的应用程序在向服务器发送数据时,等待填满缓冲区导致延迟会产生很大影响,因此一般会使用直接发送的选项。 - TCP模块对较大数据进行拆分并加入TCP头部
- IP模块负责添加两个头部,MAC头部(以太网用的头部,包含MAC地址)和IP头部(IP用的头部,包含IP地址)
- 封装好的包会被交给网络硬件-----网卡;网卡的ROM中保存着全世界唯一的MAC地址,这是在生产网卡时写入的,将这个值读出之后就可以对MAC模块进行设置,MAC模块就知道自己对应的MAC地址了。
- 传递给网卡的网络包是由一连串0和1组成的数字信息,网卡会将这些数字信息转换为电信号或光信号,并通过网线(或光纤)发送出去,然后这些信号就会到达集线器、路由器等转发设备,再由转发设备一步一步地送达接收方(分组转发)。
(1)路由器根据目标地址判断下一个路由器的位置
(2)集线器在子网中将网络包传输到下一个路由
ps: 在打开计算机启动操作系统的时候,网卡驱动程序会对硬件进行初始化操作,然后硬件才进入可以使用的状态。这些操作包括硬件错误检查、初始设置等步骤;
4.从服务器断开并删除套接字
当收发数据完成时,协议栈在设计上允许任何一方先发起断开过程,一般为完成数据发送的一方会调用socket库中的close程序,完成四次挥手过程和删除套接字过程;
5.说明
本文为《网络是怎样连接的》读书笔记,如有错误,还请兄弟们指正,大家一起进步。