- 链接
主要考察三个知识点- IP(网络层)
- TCP(传出层)
- HTTP(应用层)
- 网络层:IP(有待补充)
- 传输层:TCP/UDP
- ISO七层模型中表示层和会话层功能是什么?
- 表示层:主要用来对应用层的数据进行格式的转换,比如说:图像视频等的编解码,加密解密等。
- 会话层:主要是建立会话,例如:Session认证,断点传输
- 描述TCP头部?
- 序号(32位):传输方向上字节流的字节编号,初始的时候会被设置为一个随机的初始值(ISN),之后每次传输的时候都是在这个随机初始值的基础之上添加上次经过传输的字节大小,例如,初始编号为ISN=1024,上次传输的传输的字节流的大小是512bit,那么这次传输的字节编号就是ISN= ISN+512,序号主要是用来解决包乱序问题。
- 确认号(32bit):其值是接收方对发送方TCP报文的相应,它的数值是上次收到的TCP报文的值+1.
- 首部长度(4bit):标识首部有多少个4字节*首部长,最大为15,也就是60字节。
- 标志位(6bit):
- URG:标志紧急指针是否有效。
- AKG:标志确认号是否有效(用来确认报文段),用来解决丢包问题。
- PSH:提示接收端立即从缓存当中读走数据。
- RST :表示要求对方重新建立连接(复位报文段)
- SYN:表示请求建立一个链接(链接报文段)
- FIN:表示请求断开一个链接(断开报文段)
- 窗口(16bit):用于告知对方(发送方)接收方还能接受多少字节的数据的长度,用于数据流控。
- 校验和(16bit):接收方用CRC检验校验数据是否发生损坏。
- 三次握手过程?
- 第一次:客户端发送SYN位,SEQ_NUM=S的包到服务器(客户端-》SYN_SEND)
- 第二次:服务器端发含ACK,SYN标志位且ACK_NUM=S+1,SEQ_NUM=p的包到客户端(服务器-》SYN_RECV)
- 第三次:客户机发送含有ACK位,ACK_NUM=P+1的包到服务器(客-》RESTABLISH,服务器-》ESTABLISH)
- 四次挥手过程?
- 第一次:客户机发送含FIN位,SEQ=Q的包到服务器(客-》FIN_WAIT_1)
- 第二次:服务器发送含ACK_NUM=Q+1的包到客户端(服-》CLOSE_WAIT,客-》FIN_WAIT_2)
- 第三次:服务器发送SEQ_NUM=R的包到客户机(服务器-》LAST_ACK,客-》TIME_WAIT)
- 此处有等待
- 第四次:客户机发送最后一个含有ACK的位且ACK_NUM=R+1的包到客户机(服务器-》CLOSED)
- 为什么是三次握手四次挥手?
- 对于握手:握手只需要确认双方通信时候的初始化序号,保证通信不会乱序,(第三次握手必要性:假设服务器端的确认丢失,链接并没有断开,客户机超时重发链接请求,这样服务器会对同一个客户机保持多个链接请求,造成资源的浪费。)
- 对于挥手:TCP是双工的,所以接收方和发送方都需要一个FIN和ACK标志位,只不错一方是被动的,所以看上去就成了4次挥手。
- TCP的连接状态?
- CLOSED:初始状态
- LISTEN:服务器处于监听状态
- SYN_SEND:客户端Socket执行CONNECTION链接,发送SYN包,进入此状态。
- SYN_RECV:服务器端收到SYN包并且发送服务端SYN包进入此状态。
- ESTABLISH:表示连接建立,客户端发送了最后一个ACK标志进入此状态,服务器端接受了最后一个ACK标志进入了此状态。
- FIN_WAIT_1:终止连接的一方(通常是客户机)发送了FIN报文后进入。等待对方FIN。
- CLOSE_WAIT:(假设服务器)接收到客户机FIN包之后等待关闭的阶段。在接收到对方的FIN包之后,自然是需要立即回复ACK包的,表示已经知道断开请求。但是本方是否立即断开连接(发送FIN包)取决于是否还有数据需要发送给客户端,若有,则在发送FIN包之前均为此状态。
- FIN_WAIT_2:此时是半连接状态,即有一方要求关闭连接,等待另一方关闭。客户端接收到服务器的ACK包,但并没有立即接收到服务端的FIN包,进入FIN_WAIT_2状态。
- LAST_ACK:服务端发动最后的FIN包,等待最后的客户端ACK响应,进入此状态。
- TIME_WAIT:客户端收到服务端的FIN包,并立即发出ACK包做最后的确认,在此之后的2MSL时间称为TIME_WAIT状态。
- 解释FIN_WAIT_2,CLOSE_WAIT状态和TIME_WAIT状态?
- FIN_WAIT_2:
- 半关闭状态。
- 发送断开请求一方还有接收数据能力,但已经没有发送数据能力。
- CLOSE_WAIT状态:
- 被动关闭连接一方接收到FIN包会立即回应ACK包表示已接收到断开请求。
- 被动关闭连接一方如果还有剩余数据要发送就会进入CLOSED_WAIT状态。
- TIME_WAIT状态:
- 又叫2MSL等待状态。
- 如果客户端直接进入CLOSED状态,如果服务端没有接收到最后一次ACK包会在超时之后重新再发FIN包,此时因为客户端已经CLOSED,所以服务端就不会收到ACK而是收到RST。所以TIME_WAIT状态目的是防止最后一次握手数据没有到达对方而触发重传FIN准备的。
- 在2MSL时间内,同一个socket不能再被使用,否则有可能会和旧连接数据混淆(如果新连接和旧连接的socket相同的话)。
- 解释RTO,RTT和超时重传?
- 超时重传:发送端发送报文之后,如果长时间没有收到确认报文,则需要重发该报文,可能有一下几种情况
- 发送的数据没有达到接收端,所以对象没有响应
- 接收端接受到的数据,但是ACK报文在返回过程当中丢失
- 接收端拒接或丢弃数据
- RTO:从上一次发送数据,因为长期没有收到ACK响应,到下一次重发之间的时间间隔,就是重传间隔。
- 通常每次重传RTO是前一次重传间隔的两倍,计量单位通常是RTT,例如:1RTT,2RTT,4RTT,8RTT等等
- 重传次数达到上限之后停止重传
- RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时,大小不稳定。
- 流量控制原理?
- 目的是接收方通过TCP头窗口字段告知发送方本方可以接受的最大数据量,用以解决发送速率过快导致接收方不能接收的问题,所以流量控制是点对点控制。
- 发送窗口:用来限制发送方可以发送的数据大小,其中发送窗口的大小由接收端返回的TCP报文段中窗口字段来控制,接收方通过此字段告知发送方自己的缓冲(受系统,硬件限制)大小。
- 接受窗口:用来标记可以接受的数据大小。
- TCP是流数据,发送出去的数据流可以分为以下四个部分:已经发送且被确认部分|已经发送未被确认部分|未发送但是可以发送部分|不可发送部分,其中发送窗=已发送未确认部分+未发送但是可以发送部分。接收到的数据流可以分为:已接收|未接受但是准备接受|未接受不准备接受,接受窗=未接受但是准备接受部分。
- 发送窗内数据只有当接受到接收端某段发送数据的ACK响应的时候才移动发送窗,左边缘紧贴刚被确认的数据,接受窗也只有接受到数据且最左侧连续是才会移动接收窗口。
- 拥塞控制原理?
- 拥塞控制的目的是防止数据被过多的注入到网络当中导致网络资源(路由器,交换机等)过载,因为拥塞控制涉及到网络链路全局,所以数据全局控制,控制拥塞使用拥塞窗口,
- TCP拥塞控制算法:
- 慢开始&拥塞避免:先试探网络拥塞的程度再逐渐增大拥塞窗口,每次收到确认后拥塞窗口翻倍,直到到达阈值ssthread,这部分是慢开始,到达阈值以后每次以一个MSS为单位增长拥塞窗口大小,当发生拥塞(超时未收到确认?在什么条件下会发生拥塞?超时没有接受到确认和拥塞有什么关系?),将阈值减为原先的一半,继续执行线性增加,这个过程为拥塞避免。
- 快速重传&快速恢复 略
- 最终拥塞窗口会收敛到稳定值。
- 如何区分流量控制和拥塞控制?
- 流量控制属于通信双方协商,拥塞控制涉及通信链路全局。
- 流量控制需要通信双方各维护一个发送窗口,一个接收窗口,对任意一方,接收窗口的大小由自身决定,发送窗口的大小由接收方响应的TCP报文段中的窗口值确定,拥塞控制的拥塞窗口大小变化由试探性发送一定数据量数据探查网络状况后而自适应调整。
- 实际最终发送窗口=min{流控发送窗口,拥塞窗口}
- TCP如何提供可靠数据的传输的?
- 建立连接(标志位):通信前确认通信实体存在。
- 序号机制(序号,确认号):确保了数据是按序、完整到达
- 数据校验(校验和):CRC校验全部数据。
- 超时重传(定时器):确保因链路故障未能及时到达数据能够被多次重发
- 窗口机制(窗口):提供流量控制,避免过量发送。
- 拥塞控制:同上
- TCP socket交互过程?
- ???
- HTTP工作流程
- 一次完整的HTTP请求事务包括以下几个环节:
- 建立起客户机和服务器连接
- 建立连接之后,客户机发送一个请求给服务器
- 服务器收到请求给予响应信息
- 客户端浏览器将返回的内容解析并且呈现,断开连接
- HTTP协议结构:
- 请求报文:
- 对于HTTP请求报文,我们可以通过以下的两种方式比较直观的看到:一是浏览器在调试模式下看请求响应信息,二是通过wireshark或者tcpdump抓包实现,通过前者看到的数据更加清晰直观,通过后者抓到的数据更真实,但是无论使用哪种方式查看,得到的请求报文主题的信息都是相同的,对于请求报文,主要包括以下四个部分:每一行数据必须通过“\r\n”分割,这里可以理解为行为标识符。
- 报文头(只有一行)
- 结构: method uri version
- mehod
- HTTP请求的方法当中,一共有9中方法,但是GET和POST占了99%以上的使用的频次,GET表示向特定资源发起请求,当然也能提交部分数据,不过提交的数据以明文方式出现在URL当中,POST通常用于指定资源提交数据处理,提交的数据被包含在请求体当中,相对而言比较安全,。
- uri
- 用来指代请求的文件,+URL
- version
- HTTP协议的版本,该字段有HTTP/1.0 和HTTP/1.1两种
- 请求头(多行)
- 在HTTP/1.1当中,请求头除了Host都是可选的,包含的头五花八门,这里只介绍部分:
- Host:指定请求资源的主机和端口号,端口号默认是80
- Connection:值为keep-alive和close,keep-alive使客户端到服务器的连接持续有效,不需要每次都重连,此 功能为HTTP/1.1预设功能
- Accept:浏览器可接收的MIME类型,假设为text/html表示接收服务器回发的数据类型为text/html。如果服务器无法返回这种类型的数据,返回406错误。
- cache-control:缓存控制,Public内容可以被任何缓存所缓存,Private内容只能被缓存到私有缓存,non-cache指所有内容都不会被缓存,
- Cookie:将存储在本地的Cookie值发送给服务器,实现无状态的HTTP协议的会话跟踪。
- Content-Length:请求消息正文的长度。
- 另外
- 另有User-Agent、Accept-Encoding、Accept-Language、Accept-Charset、Content-Type等请求头这里不一一罗列。由此可见,请求报文是告知服务器请求的内容,而请求头是为了提供服务器一些关于客户机浏览器的基本信息,包括编码、是否缓存等。
- 空行(一行)
- 可选消息体(多行)
- 响应报文
- 响应报文是服务器对于请求资源的响应,通过上面提到过的方式可以看到,同样的,数据也是使用“\r\n”来分割,
- 报文头(一行)
- 结构:
- version status_code status_message
- version
- 描述所遵循的HTTP版本
- status_code
- 状态码,指明对请求处理的状态,常见的状态如下:
200:成功。
301:内容已经移动。
400:请求不能被服务器理解。
403:无权访问该文件。
404:不能找到请求文件。
500:服务器内部错误。
501:服务器不支持请求的方法。
505:服务器不支持请求的版本。
- status_message
- 显示和状态码等价的英文描述
- 响应头(多行)
- 这里只罗列部分数据
Date:表示信息发送的时间。
Server:Web服务器用来处理请求的软件信息。
Content-Encoding:Web服务器表明了自己用什么压缩方法压缩对象。
Content-Length:服务器告知浏览器自己响应的对象长度。
Content-Type:告知浏览器响应对象类型。
空行(一行)
信息体(多行)
实际有效数据,通常是HTML格式的文件,该文件被浏览器获取到之后解析呈现在浏览器中。
HTTP作为无状态协议,必然需要在某种方式保持连接状态。这里简要介绍一下Cookie和Session。 - Cookie Cookie是客户端保持状态的方法。 Cookie简单的理解就是存储由服务器发至客户端并由客户端保存的一段字符串。为了保持会话,服务器可以在响应客户端请求时将Cookie字符串放在Set-Cookie下,客户机收到Cookie之后保存这段字符串,之后再请求时候带上Cookie就可以被识别。 除了上面提到的这些,Cookie在客户端的保存形式可以有两种,一种是会话Cookie一种是持久Cookie,会话Cookie就是将服务器返回的Cookie字符串保持在内存中,关闭浏览器之后自动销毁,持久Cookie则是存储在客户端磁盘上,其有效时间在服务器响应头中被指定,在有效期内,客户端再次请求服务器时都可以直接从本地取出。需要说明的是,存储在磁盘中的Cookie是可以被多个浏览器代理所共享的。 - Session Session是服务器保持状态的方法。 首先需要明确的是,Session保存在服务器上,可以保存在数据库、文件或内存中,每个用户有独立的Session用户在客户端上记录用户的操作。我们可以理解为每个用户有一个独一无二的Session ID作为Session文件的Hash键,通过这个值可以锁定具体的Session结构的数据,这个Session结构中存储了用户操作行为。 当服务器需要识别客户端时就需要结合Cookie了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用Cookie来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在Cookie里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。如果客户端的浏览器禁用了Cookie,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如sid=xxxxx这样的参数,服务端据此来识别用户,这样就可以帮用户完成诸如用户名等信息自动填入的操作了。