计算机网络八股文
1、HTTP常见的状态码
- 1XX 提示信息,表示目前是协议处理的中间状态,还需要后续的操作;
- 2XX 成功,报文已经成功收到并被正确处理;
- 3XX 重定向,资源位置发生变动,需要客户端重新发送请求;
- 4XX 客户端错误,请求报文有误,服务器无法处理;
- 5XX 服务器错误。服务器在处理请求时内部发生了错误;
2、HTTP请求和响应的各自组成部分
HTTP通信协议由请求(Request)和响应(Response)两部分构成。每个请求和响应都由头部和主体组成,其中头部包含了各种元数据,而主体则包含了实际的内容(如果有的话)。
HTTP请求
HTTP请求包括以下字段:
- 请求行(Request Line):请求行包括HTTP方法(比如GET、POST、PUT、DELETE等)、请求的URI、以及HTTP版本。
- 请求头(Request
Headers):请求头包含了一系列的字段,每个字段都提供了一些关于请求的元数据。常见的请求头包括:
- Host: 请求的目标主机名和端口号。
- User-Agent: 发起请求的用户代理的信息,通常包括浏览器类型、版本、操作系统等信息。
- Accept: 客户端可以处理的MIME类型。
- Accept-Language: 客户端接受的语言。
- Accept-Encoding: 客户端接受的内容编码,比如gzip。
- Cookie: 客户端存储的用于服务器识别的cookie。
- Content-Type: 如果请求包含了主体,这个字段描述了主体的MIME类型。
- Content-Length: 如果请求包含了主体,这个字段描述了主体的长度。
- 请求主体(Request Body):不是所有的请求都包含主体。比如GET和HEAD请求就没有主体。但是POST和PUT请求通常会有主体,包含了要发送给服务器的数据。
HTTP响应
HTTP响应包括以下字段:
- 状态行(Status Line):状态行包括HTTP版本、状态码(比如200表示成功,404表示未找到等),以及状态描述。
- 响应头(Response
Headers):响应头包含了一系列的字段,每个字段都提供了一些关于响应的元数据。常见的响应头包括:
- Server: 发送响应的服务器的信息。
- Content-Type: 响应主体的MIME类型。
- Content-Length: 响应主体的长度。
- Content-Encoding: 响应主体的内容编码,比如gzip。
- Set-Cookie: 服务器想要设置在客户端的cookie。
- Last-Modified: 资源的最后修改日期。
- ETag: 资源的版本标识。
- 响应主体(Response Body):响应的主体包含了服务器返回的数据,比如HTML页面、图片、JSON数据等。
3、完整的HTTP请求和响应展示
让我们来看一下一对典型的HTTP请求和响应。
HTTP请求示例
假设你在浏览器中访问
http://www.example.com
,你的浏览器可能会发送如下的GET请求:
1 | GET / HTTP/1.1 |
HTTP响应示例
对于上述的请求,服务器可能会返回如下的响应:
1 | HTTP/1.1 200 OK |
这个响应表示请求成功(状态码是200),服务器返回了一个简单的HTML页面作为响应主体。响应头还包含了一些其他的信息,比如服务器类型(Apache),最后修改日期,内容长度,内容类型等。
希望这些示例可以帮助你更好地理解HTTP请求和响应!
4、TCP的KeepAlive和HTTP的Keep-Alive
TCP的KeepAlive和HTTP的Keep-Alive虽然名字类似,但实际上是两个不同级别的概念,分别在TCP和HTTP协议层级中起作用。
TCP的KeepAlive:
TCP的KeepAlive是一个底层的、可选的机制,其目的是为了检测和维护处于空闲状态的TCP连接。一旦启用,如果在特定的时间间隔内(通常在数小时)没有任何数据在TCP连接上进行交换,那么发送方就会发送一个KeepAlive数据包到接收方,而无需传输任何应用级别的数据。接收方需要对这个数据包做出响应。如果发送方在一定时间内没有收到响应,它将重发KeepAlive数据包,一般会尝试多次。如果仍然没有收到响应,发送方将假设连接已经断开,并将其关闭。
HTTP的Keep-Alive:
HTTP的Keep-Alive是在HTTP 1.1引入的,用来允许单一的TCP连接被多个HTTP请求/响应共享,而不是每个请求/响应都重新建立一个新的连接。这显著提高了网络通信的效率,因为建立和关闭TCP连接需要时间和资源。
在HTTP 1.0中,每个HTTP请求/响应都需要一个新的TCP连接,这被称为非持久连接。而在HTTP 1.1中,默认启用了Keep-Alive,也就是说默认使用持久连接,除非明确指定”Connection: close”。
当使用HTTP Keep-Alive时,HTTP请求的头部会包含一个”Connection: keep-alive”字段,这告诉服务器客户端希望保持连接以便发送更多的请求。服务器的响应也会包含一个”Connection: keep-alive”字段,这表示服务器同意保持连接。
总的来说,这两个概念都关于连接的维护,但是工作在不同的层级。TCP的KeepAlive主要是为了检测和处理僵死连接,而HTTP的Keep-Alive则是为了提高效率,通过复用已存在的TCP连接来发送多个HTTP请求/响应。
队头阻塞
这里涉及到一个小概念需要说一下:可以想象,当我们开启Keep-Alive时,我们无需像以前那样,先发送A请求,等待服务器回应,再发送B请求…..一直如此运作下去。我们可以发送A请求后,无需等待服务器响应,紧接着发送B请求。但是服务器还是按照顺序响应,先响应A请求,完成后再响应B请求。其实这里很明显感觉到会有问题,如果迟迟收不到A响应,后面的响应就更收不到了,就会造成所谓的队头阻塞问题。
在使用HTTP长连接时,如果一个客户端完成了一个HTTP请求后不在发起请求,此时这个TCP连接一直占用不就会导致浪费资源吗?
对没错,所以为了避免资源浪费的情况,web 服务软件一般都会提供
keepalive_timeout
参数,用来指定 HTTP
长连接的超时时间。
比如设置了 HTTP 长连接的超时时间是 60 秒,web 服务软件就会启动一个定时器,如果客户端在完后一个 HTTP 请求后,在 60 秒内都没有再发起新的请求,定时器的时间一到,就会触发回调函数来释放该连接。
传输层协议有哪些
UDP
和TCP
协议;
TCP
协议的特点
面向连接的:采用TCP
协议通信的双方必须通过三次握手建立连接才能开始数据的读写。完成数据交换以后,通信双方都必须断开连接,以释放内核的资源。
面向字节流的:当用户消息通过TCP
协议传输时,TCP
模块先将这些消息放入TCP
发送缓冲区,发送的时候消息可能会被操作系统分组成多个TCP
报文。注意,当我们调用send
函数的时候,消息并没有真正被发送出去,只是被拷贝到了操作系统内核协议栈中。何时被真正发送,取决于发送窗口、拥塞窗口以及当前发送缓冲区的大小等条件。
可靠的:1、TCP
采用发送应答机制,即TCP
发送端发送每一个TCP
报文段都要接收到对方的应答,才认为这个TCP
报文段传输成功;2、TCP
协议采用超时重传机制,发送端发送一个TCP
报文段之后,开启定时器,如果在规定时间内没有接收到应答,则重传此TCP
报文段;3、因为TCP
报文段最终是以IP
数据报发送的,IP
数据报到达接受方的时候可能乱序、重复,TCP协议还会对接收到的TCP报文段重排、整理,再交付给应用层。
描述TCP头部结构的大致组成部分
16位源端口号、16位目标端口号、32位序号、32位确认号、4位头部长度、6位保留、6位标志位、16位窗口大小、16位校验和、16位紧急指针
简述各部分作用
源端口号代表的是是从发送端的哪一个端口发送出来的,目的端口号代表的是发送给接收端上层应用程序的哪一个端口。
TCP
报文段的序号值等于系统初始化的某个随机值ISN
加上该报文段在字节流中的偏移(偏移值)。
确认号就是接收到的TCP
报文段的序号值加1。
4位头部长度代表TCP
报文段整个头部长度有多少个32bit
字(四字节)。
6位标志位分别为:URG
(紧急指针是否有效)、ACK
(确认号)、PSH
(接收端应立即从TCP
接收缓冲区中读走数据)、RST
(表示要求对方重新建立连接)、SYN
(请求建立一个连接)、FIN
(通知对方本端要关闭连接)。
16位窗口大小是流量控制的一个手段,他告诉对方本端的TCP
接收缓冲区还能容纳多少字节的数据。
16位校验和由发送端填充,接收端采取CRC
算法对接收到的TCP
报文段验证。
TCP连接的建立和关闭
首先,通过数据展示一下三次握手:
发送端:seq 12345 (SYN)
————-
接收端:seq 56789 (SYN)
ack 12346
————-
发送端:ack 56790
接下来是四次握手,假设发送端首先发出了断开连接请求
发:seq 12346
, ack 56790
(FIN)
—— 收:ack 12347
—— 收:seq 56790
,
ack 12347
(FIN)
——-
发:ack 56791
实际上,四次握手中的收的第一次确认报文段可以省略,因为下一次收的TCP报文段里包含了ack
。其实第一个ack
是否应该出现取决于TCP
的延迟确认特性。
TCP状态转移
服务器处于被动等待客户连接,可以简单描述一下当有客户端请求连接时,该连接服务器端的状态变化为:
LISTEN
————- SYN RCVD
—————–
ESTABLISHED
.
当客户端主动关闭连接时,服务器端状态变化为:
CLOSE_WAIT
————– LAST_ACK
.
请求连接时,客户端状态变化为,考虑connect
系统调用成功
SYN_SENT
————- ESTABLISHED
注意,connect
系统调用失败有三个原因:
1、connect
连接的目标端口不存在(未被任何线程监听)
2、connect
试图连接的端口处在TIME_WAIT
状态
3、没有收到服务器端的应答报文
connect
调用失败则返回CLOSE
状态。
客户端请求关闭时,客户端状态变化为
FIN_WAIT_1
———- (FIN_WAIT_2)
————–
TIME_WAIT
TIME_WAIT状态好好看看书的3.4.2节,讲的很好
复位报文段
什么情况下接收端会回复复位报文段?
1、发送端访问一个不存在的窗口。
2、发送端访问的服务器端的窗口仍处于TIME_WAIT
状态。
3、半打开状态向连接发送数据,会收到复位报文段。
收到复位报文段应该如何处理呢
收到复位报文段的机器应该断开连接或者重新发起连接。
半打开状态
假设现在服务器端(或者客户端)关闭或者异常终止了连接,客户端(或者服务器端)并没有接收到结束报文段,依旧保持连接状态,就称为半打开连接状态。如果此时客户端(或者服务器端)向此连接发送数据,会收到一个复位报文段的回应报文。
关于MSS
的计算
首先需要了解两个名词,一个是MTU
(MaxMaximum Transmission Unit
)是指网络传输中最大的数据包大小,MSS
(Maximum Segment Size
)是指TCP
协议中数据段的最大大小。在TCP
协议中,MSS
是由MTU
减去IP
和TCP
头部的长度得出的。
IP
头部的长度通常为20个字节,TCP
头部的长度通常为20个字节,所以MSS
的计算方法为:
MSS
= MTU
- IP
头部长度 -
TCP
头部长度
因此,在MTU
为16436字节的情况下,MSS
的计算公式为:
MSS
= 16436 - 20 - 20 = 16396
其中,20是IP
头部和TCP
头部的长度之和,这是因为IP
和TCP
协议都需要使用头部来传递各种控制信息,如源地址、目标地址、端口号、序列号、确认号等。因此,在TCP
协议中,MSS
是MTU
减去IP
和TCP
头部长度的结果。