【网络是怎样连接的】第六章 请求到达服务器以及响应给客户端(完结)

1.服务器架构
当网络包到达Web服务器后,服务器就会接收这个包并进行处理。服务器有很多种类,其硬件和操作系统与客户端相比是不一样的。但是网络相关的部分,如网卡,协议栈,Socket库什么的和客户端却别无二致。无论硬件还是OS如何变化,TCP和IP的功能都是一样的。(当然Socket库的用法以及服务器程序的结构还是不同的)

服务器的程序结构如图,我们可以把程序分为两个模块,等待连接模块a以及负责与客户端通信的模块b。

在这里插入图片描述

当服务器启动的时候就会运行等待连接模块a,这个模块负责创建套接字,然后进入等待连接的暂停状态。当客户端发起连接时候,a模块就会恢复运行并且接收连接,然后启动通信模块b,给b完成连接的套接字。然后b就会使用已连接的套接字与客户端通信。每次有新客户端连接,就会启动一个b,因此客户端和b是一对一的关系。

2.服务器建立连接的过程

接下来我们具体看服务器接受连接的过程。

首先a模块在服务器程序启动的时候就存在了,首先,协议栈会调用socket创建套接字,向套接字内写入指定要使用的端口号。接下来,协议栈会调用listen向套接字写入等待连接状态这一控制信息,这样套接字就进入等待连接状态。然后协议栈就会调用accept来接受连接,然后马上暂停程序运行。等待网络包真正到达了,再继续进程。

一旦客户端包到达,程序就会返回相应包然后接受连接操作。A模块会给等待连接的套接字复制一个副本,将客户端套接字与这个副本连在一起。然后启动b模块,将副本交给b模块。之后就进行数据收发操作了。

为什么要复制一个套接字副本而不是直接将这个套接字交给b呢?因为如果不创建新的,则这个套接字交给b模块后,就没有套接字等待连接了,如果有其他客户端发起连接就会遇到问题。

那么既然套接字都是复制于一个母本,那么这些套接字的端口号必然都是一样的。那么一个网络包到达后,如果协议栈只看TCP头部接收方端口号,就无法判断要将包交给哪个套接字了。

解决方案就是,不仅仅只看接收方端口号,协议栈要通过客户端IP地址,端口号,服务端IP地址,端口号来共同确定要把包交给哪个套接字。如图所示

在这里插入图片描述

3. 服务器接收操作
5. 在这里插入图片描述

下面详细叙述服务器接收网络包的时候的操作,假定这是一个TCP网络包。

MAC模块

首先是网卡中的MAC模块负责,网卡接收到信号后,根据报头信号变化提取时钟信号,然后利用这个时钟信号还原数字信息。
在这里插入图片描述

接下来查看包末尾的帧校验序列FCS来校验是否错误,如果发现数据已经因为噪声等影响导致信号失真,则丢弃该网络包。

当FCS校验通过,此时检查MAC头部中的接收方MAC地址,看看这个包是不是发给自己的。

如果是自己的,就将信息保存在网卡的缓冲区中,调用中断,让CPU来处理接收到的网络包。CPU根据MAC头部的以太类型字段判断协议种类,这里,一台类型的值表示IP协议,因此会调用TCP/IP协议栈,并将包转交给它。

IP模块

然后就到IP模块开始工作。IP模块会检查IP头部格式是否规范,然后看看接收方IP地址是不是写着自己。当服务器有类似路由器的包转发功能时,对于不是自己的包也会向路由器那样根据路由表对包转发。

如果是自己,接下来检查包有没有被分片(分片的话IP报头会有个标志),如果分片了就暂存在内存中,等分片全部到达再一起组装起来。然后检查IP头部的协议号字段,发现是TCP协议,则转交给TCP字段处理。

TCP模块
如果TCP头部的SYN为1,表示这是一个发起连接的包,这是TCP模块会检查TCP报头中接收方的端口号,确认有没有相同端口号并且在等待连接的套接字。如果没有则向客户端返回包含错误通知的包。

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

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

在这里插入图片描述

如果TCP模块此时接收的是一个数据包,则检查IP模块和TCP模块中的双方IP地址和端口号信息,然后找到这些信息全都匹配的套接字。然后根据这个套接字中保存的上一个的序号和数据长度计算应该接收到的包的序号,然后与TCP头部的序号比对一番,看看有没有丢包。如果一直,则TCP会从包中取出数据,放到接收缓冲区中,与缓冲区中上次收到的数据块连接起来。

之后TCP会生成确认应答数据包,根据包序号和数据长度计算出ACK号,委托IP模块发给客户端。(在返回这个包之前,会先等一段时间,看看能不能和后续的应答包合并)

然后就是TCP模块的断开操作,具体参考之前写的内容,非常详细。这里不再赘述。

5.服务器返回响应消息

当服务器完成对请求消息的各种处理之后,就可以返回响应消息了。这里的工作过程和客户端向服务器发送请求消息时的过程相同。

首先,Web服务器调用Socket库的write,将响应消息交给协议栈。这时,需要告诉协议栈这个响应消息应该发给谁,但我们并不需要直接告知客户端的IP地址等信息,而是只需要给出表示通信使用的套接字的描述符就可以了。套接字中保存了所有的通信状态,其中也包括通信对象的信息,因此只要有描述符就万事大吉了。

接下来,协议栈会将数据拆分成多个网络包,然后加上头部发送出去。这些包中包含接收方客户端的地址,它们将经过交换机和路由器的转发,通过互联网最终到达客户端。

附上整个网络包的旅程全图

在这里插入图片描述

在这里插入图片描述

到这里整本书的内容就结束了,我只是简略概括书中的大致内容,也省略了一些我认为不必要的内容。这真是一本非常好的入门书籍,看完后我感觉对于计算机网络的整个大框架都有了。接下来就应该去深入地啃一些书籍。
路漫漫其修远兮,吾将上下而求索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值