第二章——探索操作系统中网络控制软件(协议栈)和网络硬件(网卡)
在有感1最后简单的讲了准备好http消息和IP地址后要委托操作系统协议栈来传达消息,今天来具体讲一下,里面的的内容其实原比我想象的严谨且复杂的,分为6个小节来理解一下:
(1)创建套接字
(2)连接服务器
(3)收发数据
(4)从服务器断开并删除套接字
(5)IP与以太网的包收发操作
(6)UPD协议的收发操作
上图中上层会向下层逐层委派工作
应用程序调用Socket库中的解析器,向DNS服务器查询IP地址,在有感1已经说过了….
我们基于这个图来讲解一下:下面先来说下协议栈TCP的部分:
1.1创建套接字
在协议栈中有着一块通信时用于存放控制信息的内存空间,例如通信对象的IP地址,端口号,通信时的状态信息。套接字本来就是一个概念不存在实体,如果非要给套接字定义的话,那么就是这块存放控制信息的内存空间。所谓的控制信息,例如客户端给服务器发送了请求消息,,因为可能消息会丢失,需要服务器响应说:“我收到了消息”,这就是控制信息,套接字必须要记录是否收到了响应,并记录响应的时间,如果丢失才能根据这些信息重新发送。
在创建套接字的时候,给他分配相应的内存空间,向其写入初始状态比如控制信息:“即将开始通信”,如分配用于临时收发数据的缓冲区空间。还有就是他会有一个标号:描述符,需要将这个描述符告知应用程序,应用程序委托协议栈进行收发数据的时候告诉协议栈你应该用这个套接字,由于套接字存放各种控制信息,协议栈就知道了该和谁通信了,也就是说协议栈是通过套接字中记录的信息来工作的。
1.2连接服务器
创建完套接字后,应用程序调用Socket中的connect,随后双方的套接字就会连接,连接的本质就是双方控制信息的交换,在连接这个阶段,首先需要的申请进行数据收发时的内存空间,这块内存空间叫做缓冲区;既然要进行控制信息的交换,客户端应用程序需要把对方的IP地址端口号等信息给协议栈,数据收发的时候才知道是谁进行数据的收发。
1.2.1控制信息
既然连接的时候讲到了控制信息,那就来具体的讲一下,控制信息大致分为两类:
1.第一类控制信息:客户端和服务器相互联络时的控制信息,这些控制信息在整个通信的过程中都都需要,不仅是连接过程,包括后面的数据收发和断开操作,这些控制信息都会放在通信传递的网络包的开头,因此被称为头部。
在连接阶段,还没有进行数据的收发,意思就是说没有数据,只有头部(上述的第一类控制信息);
第一类控制信息(TCP头部)具体就是下表的这些。
不仅是发送方有头部,接收方也有头部,在整个通信过程中,这种控制信息全局存在用来通信的,比如说:
发送方:我有你的IP地址了,我要开始通讯了
接收方:我准备好了
发送方:现在发送的是1号数据
接收放:1号数据我已经收到
头部的信息非常重要,知道了头部的信息,其实就理解了通信的整个过程。
2.第二类控制信息:就是前面1.1创建套接字中讲到的保存在套接字里的控制信息,这些信息包括接收方发过来的消息,收发数据执行操作的状态信息等,这些套接字里的信息控制着协议栈的操作。
1.2续
接着连接阶段讲,来讲点具体是怎么发送消息的,首先客户端方会建立含有对方的信息的TCP头部,打包成小块小块的网络包接下来TCP模块会委托IP模块来发送信息给服务器端,然后服务器端的IP模块收到消息将消息又传送到TCP模块,TCP模块根据对方TCP头部传来的端口找到对应的套接字,之后套接字会更新状态信息“正在连接”。以上过程完成,服务器TCP模块会发出收到信息的响应发送给客户端,与上面的过程相反,基本相同,需要在头部写上对方的IP和端口号还有SNY比特,SYN为1表示连接成功;再将ACK控制位设为1,这表示收到了你发送的包了;然后委托IP模块发送给客户端的IP模块,又到客户端的TCP模块,如果连接成功,客户端的套接字会存入服务器端的IP地址,端口号,将状态置为连接完毕,到这里还有最后一个步骤,将自己的ACK号置为1发送给服务器端,表示我接收到了你的响应啦,到这里连接操作全部完成,在调用close之前,这个无形的连接管道一直存在。
1.3收发数据
协议栈是不会管发送的什么数据的,应用程序给数据他就发送,但是不会马上发送,而是堆积在连接阶段申请的缓冲区里一段时间在发送,那要堆积到什么程度发送呢,有两个判断时机,一个是时间,如果应用程序老半天也不发送数据过来,就是说发送数据的频率太低了,这是协议栈有一个计时器,到点了就必须发送了;还有一个就是网络包能容纳的最大数据长度,协议栈会根据一个叫做MTU的参数来判断,MTU表示一个网络包的最大数据长度,MTU是含头部的最大长度,MSS表示减去头部长度的最大长度,当应用程序发送数据的长度接近MSS的长度或者大于MSS时,就发送出去,这样就能避免发送大量的小包数据了。