(83条消息) 《网络是怎样连接的》(一)_qq_38480311的博客-CSDN博客
本文主要取材于 《网络是怎样连接的》 第二章。
目录
(1)创建套接字
(2)连接服务器
(3)收发数据
(4)从服务器断开连接
TCP 整体流程
简述:将探索操作系统中的网络控制软件(协议栈)和网络硬件(网卡)是如何将浏览器的消息发送给服务器的。
客户端会创建套接字(一块内存),记录控制信息,然后协议炸根据套接字里的内容去和服务端连接。服务端的套接字是提前创建好的,等待客户端过来连接,连接过程双方各会开辟一块内存,叫做缓冲区缓冲数据。连接服务器实际是发送控制包到服务器,包头里包含着客户端的信息,这个包相当于去建“管道”的工人。连接建好后发送数据时,数据会在缓存区到达一定数量时才发送(为了避免频繁的小包),此过程中 通过发送端的序号以及接收端的ACK号可以判断包是否正确收到。收到的包在接收端也会先存到缓冲区,进行原始数据组合之后提交给应用。通信结束之后,会进行断开(断开是四次握手),删除套接字。
本章共六个章节,主要理解前四节,上一章提到 收发数据操作(TCP/IP)是以下四个步骤:
(1)创建套接字(创建套接字阶段)(2)将管道连接到服务器端的套接字上(连接阶段)(3)收发数据(通信阶段)(4)断开管道并删除套接字(断开阶段)
(1)创建套接字
从应用程序收到委托后,协议栈通过TCP协议收发数据的操作可以分为4个阶段。首先是创建套接字,在这个阶段,我们将介绍协议栈的内部结构、套接字的实体,以及创建套接字的操作过程。到这里,大家应该可以对套接字到底是什么样的一个东西有一个比较具体的理解。
如何理解协议栈?
协议栈就是一套规则,如上图所示,上下层有一定的规则,上层会委派下层去做一些工作,下层按照上层的指示执行工作。
应用程序的下面是Socket库,其中包括解析器,解析器用来向DNS服务器发出查询IP,详见第一章。
操作系统 协议栈的上半部分有两块,分别是负责用TCP协议收发数据的部分和负责用UDP协议收发数据的部分,它们会接受应用程序的委托执行收发数据的操作。
下面一半是用IP协议控制网络包收发操作的部分。在互联网上传送数据时,数据会被切分成一个一个的网络包。
IP下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,也就是对网线中的信号执行发送和接收的操作。
套接字是什么?如何生成的?
套接字只是一个概念,不存在实体,如果一定要赋予它一个实体,这些控制信息就是套接字的实体。协议栈在执行操作时需要参阅这些控制信息,如套接字中的通信对象IP地址和端口号,以便向指定的IP地址和端口发送数据。
创建套接字,就是先开辟一个内存空间,将控制信息写入。接下来需要把套接字的描述符给应用程序,即把自己的号码牌给app,让app知道用哪个套接字通信。接下来,当app委托协议栈发送消息时,只需要提供描述符即可。创捷套接字之后,浏览器会调用connect,协议栈会将本地套接字与服务器套接字进行连接。
对套接字的理解:当于是一块记录了控制信息的牌子。假如我是app一个快递收发大户,我每次发快递需要告诉快递员 我这个快递需要发给谁,地址是什么,电话是什么,如果每次都说,我很累。
但是,假如我把我需要的发货地址信息全部编号,写在一张张号码牌上(即创建套接字)。
我只需要告诉快递员快递的发货信息是几号就行(调用cennect进行连接,让协议栈知道ip等信息),比如我(app)拿了个快递(消息),给快递员(协议栈)说,这个快递给我发1号,快递员自己会找1号对应的地址,各类信息等等。
服务器也会创建套接字。但是服务器的套接字并不知道通信对象是谁,因为连服务器上的app自己都不知道通信对象是谁。所以需要客户端过来请求,告诉服务器,“我想和你通信,我的ip是**,端口号是&&,我们通信吧。” 此外,当执行数据收发操作时,我们还需要一块用来临时存放要收发的数据的内存空间,这块内存空间称为缓冲区,它也是在连接操作的过程中分配的。
(2)连接服务器
接下来是客户端套接字向服务器套接字进行连接的阶段。我们将介绍“连接”具体是进行怎样的操作,在这个过程中协议栈到底是如何工作的,以及客户端和服务器是如何进行交互的。
客户端先创建一个包含表示开始数据收发操作的控制信息的头部, 然后 TCP会将头部委托给IP模块,IP模块执行包发送,包到达服务器, 服务器上的IPI将接收到的数据传递给TCP模块,服务器的TCP模块根据TCP头部中的信息找到端口号对应的套接字,然后套接字中会写入相应的信息,并将状态改为正在连接。
这个过程TCP头部中请求 有SYN = 1,表示请求,服务器收到包后 相应将ACK控制位设为1, 然后 客户端会再回一个 ACK控制位设为1。 这个应该就是TCP三次握手的过程。
(3)收发数据
连接好之后,双方怎么发数据呢?
为避免频繁小包,协议栈会将数据存放在内部的发送缓冲区,等到数据累计一定数量发,或者等待一段时间若数据不满也发送(避免响应太迟);对于非常大的数据拆分为小包发送。那么对于发送的数据如何确定收到呢?拆分的数据怎么组装呢?TCP模块会拆分数据,算好每一块数据相当于从头开始的第几个字节,将算好的字节数写在TCP头部中,“序号”字段就是派在这个用场上的。收端收到了包回复ACK号,通过“序号”和“ACK号”可以确认接收方是否收到了网络包(可以判断丢失重发等)。当接收方的TCP收到包后,会先将数据存放到接收缓冲区中,然后将数据块组装起来还原成原本的数据并传递给应用程序。
(4)从服务器断开连接
并删除套接字收发消息的操作全部结束之后,接下来要断开服务器的连接并删除套接字。断开操作的本质是当消息收发完成后客户端和服务器相互进行确认的过程。
服务器和客户端 谁都可以选择先断开。
若客户端先发起断开,则断开的操作顺序如下。
(1)客户端发送FIN(2)服务器返回ACK号(3)服务器发送FIN(4)客户端返回ACK号
服务断开后,一般套接字 需要等几分钟再删除。(例如第三步发的FIN重发了,在网络中呆了好久到达客户端,客户端的端口已经被新的套接字占用了,然后新的连接可能就断了)