前言
计算机网络是每个开发者必须掌握的技能,在大量的面试中我们也经常会被问到相关的问题。所以在此我准备复盘一下自己掌握的计算机网络相关的知识,同时将掌握的网络相关知识串通起来以便更好的理解吸收。
计算机网络分层
对于网络的分层我们一般了解到的有两种:ISO(国际化标准组织)制定的OSI七层模型;TCP/IP四层网络模型。OSI七层模型属于学术上制定的国际标准,偏向于理论标准,TCP/IP更接近于实际使用的国际化标准,被广泛应用在生活中的网络实现中。两者的关系可以看下图:
图1.0 OSI模型与TCP/IP的关系.jpg注:在网络上我们可能也会看到五层模型,它和四层模型的区别就是在OSI模型中的数据链路层和物理层。五层模型将其分为两层,四层模型将其合并为一层。
OSI参考模型各层的含义:
- 应用层:各种应用程序协议,如HTTP协议(超文本传输协议)、FTP协议(文件传输协议)、SMTP协议(简单邮件传输协议)、POP3(邮局协议第三版)等;
- 表示层:信息的语法语义以及它们的关联,如加密、解密、转换翻译、压缩、解压缩等;
- 会话层:不同机器上的用户之间建立及管理会话;
- 传输层:接收上一层的数据,在必要的时候把数据进行分割,并将这些数据交给网络层,并保证这些数据段有效到达对端;
- 网络层:控制子网的运行,如逻辑地址、分组传输、路由选择;
- 数据链路层 :物理寻址,同时将原比特流转变为逻辑传输线路;
- 物理层:机械、电子、定时接口通信道上的原始比特流传输;
HTTP协议
- HTTP协议是建立在TCP/IP协议之上的,是一个应用层的协议,默认端口号是80;
- 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型有content-type加以标记;
- 无连接:指的是限制每次连接只处理一个请求。服务端处理完客户端的请求,并收到客户端的应答后,即断开连接。
- 无状态:HTTP协议是无状态的协议。指的是协议对于事务处理没有记忆的能力。缺少状态意味着如果后续处理需要前面的状态,则它必须重传;
HTTP请求方法
http/1.1
规定了以下请求方法:
-
GET
:通常用来获取资源 -
PUT
:修改数据 -
POST
:向服务器提交数据 -
DELETE
:删除资源 -
OPTIONS
:列出可对资源实行的请求方法,主要用来跨域请求 -
HEAD
:获取资源的元信息 -
CONNECT
:建立连接隧道,用于代理服务器 -
TRACE
:追踪请求-响应的传输路径
GET和POST的区别
- 从缓存来说,GET会被浏览器主动缓存下来,会留下历史记录,而POST是不会的,除非手动设置。
- GET是幂等的,POST不是。幂等指的是执行相同的操作,结果也是相同的。
- GET参数一般放在URL中,POST放在请求体中。
- GEt只能进行URL编码,而POST支持多种编码格式。
- GET请求在URL传送的参数是有长度限制的,而POST是没有的。
- GET参数的数据类型只能接收ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能传递敏感信息。
URL的结构
URL请求的结构一般都是如下结构:
图 2.0 URL结构.png
Request Headers 和 Response Headers
HTTP请求的Request headers如下图:
图3.0 请求Header.png
HTTP请求的Response Headers如下图:
图 4.0 响应Header.png
Request Header的起始行为:
POST /aas.do HTTP/1.1
也就是方法 + 路径 + http版本。
content-type
:指示资源的媒体类型。图中所示内容类型为html的文本类型,文字编码方式为utf-8
user-agent
:用户代理,标记系统和浏览器内核
cookie
:浏览器cookie
accept
:通知服务器可以返回的数据类型
accept-encoding
:编码算法,通常是压缩算法,可用于发送回的资源
accept-language
:通知服务器预期发送回的语言类型。这是一个提示,并不一定由用户完全控制:服务器应该始终注意不要覆盖用户的显式选择(比如从下拉列表中选择语言)
conenction
:链接状态
HTTP请求的Response Header:
content-encoding
:用于指定压缩算法
ETag
:缓存标识符
last-modified
:上次内容修改的日期,为6月8号
content-type
:指示资源的媒体类型。图中所示内容类型为html的文本类型,
Date
:响应时间
HTTP状态码
HTTP状态码是用以表示网页服务器超文本传输协议响应状态的3位数字代码。被分为5类:
-
1xx:表示临时响应并需要请求者继续执行操作的状态码。
100(继续)继续请求者应当继续提出请求。服务器返回此状态码表示已收到的第一部分,正在等待其余部分。
101(切换协议)请求者已要求服务器切换协议,服务器已确认并准备切换。 -
2xx:表示成功处理的请求的状态码。
200(成功)服务器已成功处理了请求,通常在响应体中会返回数据。
202(接收)服务器已接受请求,但尚未处理。最终该请求也可能不会被执行,并且可能在处理发生时被禁止。
204(无内容)含义和200相同,但响应头后没有body数据。
206(部分内容)服务器成功处理了部分GET请求,它的使用场景为HTTP分块下载和断点续传,当然也会带上相应的响应头字段Content-Range
。 -
3xx:表示要完成请求,需要进一步操作。通常这类状态用来重定向。
301(永久移动)永久重定向。
302(临时移动)临时重定向。
304(未修改)从上次请求后,请求的网页未修改过。一般和客户端协商缓存返回这个状态码。 -
4xx:表示请求出错了,妨碍了服务器的处理。
400(错误请求)表示由于明显的客户端错误(例如:格式错误的请求语法,太大的大小),服务器不能或不会处理该请求。
401(未授权)请求要求身份验证,对于需要登录的网页,服务器可能返回此状态码。
403(禁止)服务器禁止请求。
404(未找到)服务器找不到请求地址的网页。
405(不被允许)请求方法不被服务端允许。
408(请求超时)服务器在等待请求时超时。 -
5xx:表示服务器在处理请求是发生内部错误。
500(服务器内部错误)服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
TCP三次握手和四次挥手
TCP需要三次握手才能建立连接,下面来看一下TCP报文头部结构:
源端口、目标端口
:源iP、源端口、目标IP、目标端口组成了链接的唯一标识序列号(Sequence number)
:指的是报文段第一个字节的序列号,序列号在TCP通信过程中有两个作用:
- 在SYN报文中交换彼此的初始序列号。
- 保证数据包按正确的顺序组装。
确认号ACK(Acknowledgment number)
:用来告知对方下一个期望接收的序列号,小于ACK的所有字节全部收到。
窗口大小(Window Size)
:占用两个字节,也就是16位。TCP引入了窗口缩放的选项可以将窗口值扩大为原来的2^n次方。
校验和(Checksum)
:占用两个字节,防止传输中数据包有损坏,如果遇到
校验和有差错的报文,TCP直接丢弃,等待重传。
可选项(Options)
:可选项的格式为:种类(Kind)1byte + 长度(Length)1byte + 值(value)。
常用的可选项有一下几个:
- TimeStamp:TCP时间戳,后面详细介绍。
- MSS:指的是TCP允许的从对方接受的最大报文段。
- SACK:选择确认选项。
- Window Scale:窗口缩放选项。
三次握手
TCP的三次握手是指建立一个TCP连接时,需要客户端和服务器总共发送3个数据包。三次握手主要是为了确认了双方的发送能力
和接收能力
是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。
下面是三次握手的过程:
刚开始客户端和服务端都处于
CLOSED
状态。然后服务端会被动的进入LISTEN状态。
- 第一次握手:客户端发送SYN数据包(SYN=j)到服务器,并进入SYN_SENT状态,等待服务器确认。
- 第二次握手:服务端收到SYN数据包,必须确认客户端的SYN(ack=j+1),同时自己也发送一个SYN数据包(SYN=k),即SYN+ACK数据包,此时服务器进入SYN——RECEIVED状态。
- 第三次握手:客户端收到服务器的SYN+ACK数据包,向服务器发送确认数据包ACK(ack=k+1),发送完次数据包,客户端进入ESTABLISHED状态,当服务端收到客户端发送的数据包也会进入ESTABLISHED状态,至此TCP握手完成(TCP连接成功)。
三次握手的原因
在谢希仁著的《计算机网络》中有讲到三次握手
的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误
,其中有这样一个例子:client发出的一个连接请求报文段因为在某个网络节点长时间逗留,而导致出现失效的报文段。当这个失效的报文段延误到连接释放以后的某个时间点才到达server。本来这是一个失效的报文段,但sever收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认报文,就建立了新的连接。由于现在client并没有发出建立连接的请求,因此不会理财server的确认报文,也不会向server发送数据。但server却以为新的传输连接已经建立,并一直等待client发来的数据。这样,server的很多资源就白白浪费了。
采用三次握手可以防止上述问题的发生。像上面这种情况,client不会向server的确认报文发出确认,server由于收不到确认报文,就知道client并没有要求建立连接。
同时在三次握手中知道也可以确认client
和server
的接收能力和发送能力没有问题。
在第一次握手时,client
向server
发送数据包,当server
端接收到数据包就能确认client
的发送能力。第二次握手,server
发送确认数据包,client
收到server
的确认数据包,就能确认sever
的接收能力和发送能力。第三次握手,client
发送确认包,当server
端收到确认包就能确认client
的接收能力。
网友评论