网络是怎样连接的(六)
请求到达Web服务器,响应返回浏览器
学习笔记
# 6.1 服务器概览 首先要大体弄懂服务器是个啥 ## 6.1.1客户端与服务器的区别 服务器启动之后,需要进行各种准备工作,弄懂包括这些准备工作在内的服务器整体结构是很重要的。
话说回来,到底啥区别呢?
- 硬件与操作系统可能有所不同的
- 客户端发起连接,而服务器等待连接,也就是调用Socket库的方式不一样吧
有何相同之处?
- 网卡、协议栈、Socket库等功能与客户端别无二致
- 因此,客户端也可以作为服务器使用
## 6.1.2 服务器程序的结构 - 服务器一般会有多个客户端连接,为了把握每个客户端的运行状态,一般采用一对一的形式。 - 服务器程序的结构分为两个模块,等待连接模块和与客户端通信的模块 - 看懂下面的图: ![一对一](https://upload-images.jianshu.io/upload_images/17108100-a40bc8c96d6b7166.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 6.1.3 服务器端的套接字和端口号 **我理解的流程:** 1. 协议栈调用Socket创建套接字; 2. 调用bind写入端口号,端口号根据服务器的种类,根据规则确定,如Web服务器的端口号80; 3. 调用listen来写入等待连接状态; 4. 当包到达时,调用accept,复制套接字,将控制信息写入新的套接字中 ![服务器端的通信操作](https://upload-images.jianshu.io/upload_images/17108100-fb20d2f3a177fa49.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![复制套接字](https://upload-images.jianshu.io/upload_images/17108100-2d861936d9e38e43.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![分配接受到的包](https://upload-images.jianshu.io/upload_images/17108100-2079efbcee9559bf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
注意事项:
- 为了让客户端正确识别程序,套接字副本的端口号必须和原套接字一致;
- 如果有多个客户端连接,可以用客户端的ip和端口号来区分不同的套接字;
为什么使用描述符呢?
我的想法:1.为了提高效率,套接字可能会复制多个副本,由于还未连接,没有客户端ip和端口号信息,而这些套接字的服务器端口号又是相同的,为了区分它们,就使用描述符;2.使用描述符这一种信息比较简单
#6.2 服务器的接受操作 主要是对包的操作 网卡→IP模块→TCP/UDP模块 ![包](https://upload-images.jianshu.io/upload_images/17108100-9c1bc112ba462e6b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
##6.2.1 网卡将接受到的信号转换成数字信息 **1.把光信号或者电信号还原成数字信息** 不同格式的信号工作方式会有些许差异,10BASE-T工作方式如下 - 根据报头的变化频率同步时钟信号,再根据时钟信号把信号还原为数字信息; - 校验包末尾的FCS和MAC头部中的MAC地址; - 还原后的数字信息被保存在网卡的缓冲区中; - 通过中断通知CPU,读取缓冲区的数据,根据MAC头部的以太类型字段判断协议种类,并调用相应软件;如字段值表示IP协议,就会调用TCP/IP协议栈
##6.2.2 IP模块接受操作 >协议栈的IP模块会检查IP头部,(1)判断是不是发给自己的;(2)判断网络包是否经过分片;(3)将包转发给TCP或者UDP模块
##6.2.3 TCP模块如何处理连接包 如何处理发起连接的包,即如何处理控制为SYN为1的包 >TCP模块会(1)确认TCP头部的控制位SYN;(2)检查接收方端口号;(3)未响应的等待连接套接字复制一个新的副本;(4)记录发送方IP地址和端口号等信息。
注意:如果相应端口没有处于等待连接模块的套接字则会返回错误
## 6.2.4 TCP如何处理数据包 1. 根据四种信息找到套接字 2. 校验控制信息,如包的序号是否可以衔接,判断是否丢失 3. 拼合包,保存在缓冲区 4. 向客户端返回ACK
##6.2.5 TCP模块的断开操作 在HTTP1.1 中 客户端先发起FIN, 服务器返回ACK,然后发送FIN,客户端返回ACK。一段时间后套接字被删除。
#6.3 Web服务器程序解释请求消息并作出响应 ##6.3.1 将请求的URL转换为实际的文件名 Web服务器公开的目录不一定是磁盘上的真是目录,需要经过一定的转换 ##6.3.2 运行CGI程序 - URL不一定指向文件,还可能指向程序,如果是指向程序,则运行相应程序 - 如果方法为GET,则将URL后面的参数传递给程序;如果方法为POST,则将消息体中的数据传给程序 - 运行结果返回服务器 ![示例](https://upload-images.jianshu.io/upload_images/17108100-65fc68d384417759.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![流程](https://upload-images.jianshu.io/upload_images/17108100-6f5edc593186c170.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ##6.3.3 Web服务器的访问控制 不能让服务器中的数据不加限制的完全暴露 三种方式:客户端IP,客户端域名、用户名和密码 **注意:**第二种方式需要向DNS服务器发送IP地址反查域名,再根据域名再查询IP是否与之前IP一致,这是为了防止注册虚假域名攻击。
## 6.3.4 返回响应消息 调用Socket库中的write,将消息传给协议栈,同时给出描述符。协议栈根据描述符对应套接字内控制信息,进行发送操作。
## 6.4 浏览器接受响应并显示内容 先记住这些: - 根据Content-Type判断数据类型 - 浏览器对操作系统发出指令在屏幕上显示信息
完。