网络基础
TCP三次握手四次挥手
TCP三次握手
所谓三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个报文
因为TCP为了解决可靠问题弄了效率方案,不用一个包一个ACK,那么就涉及到了在流水线中有多个数据包和ACK包在乱序流动,他们之间对应关系就乱掉了的顺序问题。使用seq和ack来控制顺序
TCP三次握手的seq和ack号的理解
TCP协议报文
三次握手过程
- 第一次:client客户端将TCP报文标志位SYN置为1,并随机产生一个序号值seq=J保存在TCP首部的序号字段里,并将该数据包发送给服务端,发送完毕后,client客户端进入SYN_SENT状态,等待服务端确认
- 第二次:服务端收到数据包后由标志位SYN=1知道客户端请求连接,于是服务端将TCP报文标志位SYN和ACK都置为1,ack=J+1,并随机产生一个序号值seq=K,并将该数据包发送给客户端以确认连接请求,服务端进入SYN_RCVD状态
- 第三次:客户端收到确认后,将标志位ACK置为1,ack=K+1,并将该数据包发送给服务端。服务端检查ack是否为K+1,ACK是否为1,正确则连接建立成功,客户端和服务端进入established状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
为什么三次?两次行不行
为了建立可靠的通信通道,保证客户端与服务端同时具备发送、接收数据能力(比如服务端相应进程还没有准备好或是挂掉了,客户端就开始发送数据包,会导致浪费)
两次是不行的,原因:
- 防止已经失效的请求报文又传送到了服务端,建立了多余的链接,浪费了资源
- 两次握手只能保证单向连接是畅通的。(为了实现可靠传输,TCP协议的通信双方,都会维护一个序列号,如果只是两次握手,最多只有连接发起方的起始序列号能被确认,另一端选择的序列号无法被确认)
TCP四次挥手
- 第一次:客户端发送TCP连接释放报文,将报文首部FIN置为1,设置序号seq=u,此时客户端进入FIN_WAIT_1状态。TCP规定:FIN报文段即使不携带数据,也要消耗一个序号
- 第二次:服务端收到客户端发送的FIN报文,向客户端返回一个ACK报文段,ack=u+1,并带上自己的序号seq=v,此时,服务端就进入了CLOSE_WAIT(关闭等待)状态,client收到服务端发送的ACK报文以后,client进入FIN_WAIT_2状态,等待服务端发送连接释放报文(在这之前还需要接受服务端发送的最后的数据)
(此时TCP服务器通知高层应用进程,客户端向服务端的方向就释放了,这时处于半关闭状态,此时client已经没有数据要发送了,但是服务端若发送数据,client依然要接受,这个状态还需要持续一段时间,即CLOSE_WAIT状态持续的时间) - 第三次:服务端将最后的数据发送完毕后,向client发送连接释放报文,FIN置为1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务端进入了LAST_ACK状态
- 第四次:client收到服务端发送的FIN连接释放报文以后,向服务端发送ACK报文段,ACK=1,ack=w+1,seq=u+1,然后client进入TIME_WAIT(时间等待)状态,而服务端收到client的ACK报文以后,就关闭连接进入CLOSED状态。而client等待2MSL(最长报文段寿命)的时间后依然没有说到回复,则证明server端已正常关闭,那么client就可以关闭连接进入CLOSED状态
可以看到:服务端结束TCP连接的时间要比客户端早一些
为什么连接的时候是三次握手,关闭的时候是四次握手
因为服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文用来应答,SYN用来同步。
但是当关闭连接的时候,服务端收到客户端的FIN报文的时候,很可能还有数据需要发送,因此不会立即关闭socket,所以只能回复一个ACK报文,告诉client:你的FIN报文我收到了,只有等我服务端的所有数据发送完了,我才能发送FIN报文。因此不能一起发送FIN+ACK报文,需要分开发,因此需要四次挥手
为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回CLOSE状态
2MSL(Maximum Segment Lifetime):指一个片段在网络中存活的最大时间,2MSL就是一个发送和一个回复所需的最大时间。
我们必须假设网络是不可靠的,有可能client发给服务端的最后一个ACK报文丢失,服务端如果没收到ACK,将不断重复发送FIN报文段,所以client不能立即关闭,它必须确认服务端收到了该ACK。client会在发送出ACK之后进入TIME_WAIT状态。所以TIME_WAIT就是用来重发可能丢失的ACK报文
client会设置一个定时器,等待2MSL时间,如果在该时间内再次收到FIN,那么client会重发ACK并再次等待2MSL
如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接
如何查看TIME_WAIT状态的链接数量
netstat -an|grep TIME_WAIT|wc -l
为什么为TIME_WAIT过多?解决方式是如何?
可能原因:高并发短连接的TCP服务器上
1、OSI与TCP/IP模型
国际标准化组织ISO与1984年提出开放系统互联(OSI)参考模型
美国国防部的TCP/IP
OSI七层:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层
TCP/IP五层:物理层,数据链路层,网络层,传输层,应用层
2、常见网络分层
物理层:集线器、(中继器)
数据链路层:网卡,网桥,交换机
网络层:IP、(ICMP、路由器、防火墙)
传输层:TCP、UDP
应用层:HTTP、SMTP、DNS、FTP
SMTP:Simple Message Transfer Protocol 简单邮件传输协议
DNS:Domain Name System 域名系统
FTP:File Transfer Protocol 文件传输协议
3、TCP和UDP区别以及使用场景
特点 | 性能 | 应用场景 | 首部字节 | |
---|---|---|---|---|
TCP | 面向连接,可靠,基于字节流 | 传输速度慢,所需资源多 | 文件,邮件传输 | 20-60字节 |
UDP | 无连接,不可靠,基于数据报文段 | 传输速度快,所需资源少 | 视频,直播,语音 | 8字节 |
TCP适用于对效率要求低,对准确性要求高要求有连接的场景
UDP适用于对效率要求高,对准确性要求低的场景
详细
什么叫做基于字节流呢?
很简单,TCP 在建立连接时,需要告诉对方 MSS(最大报文段大小)。
也就是说,如果要发送的数据很大,在 TCP 层是需要按照 MSS 来切割成一个个的 TCP 报文段的
切割的时候我才不管你原来的数据表示什么意思,需要在哪里断句啥的,我就把它当成一串毫无意义的字节,在我想要切割的地方咔嚓就来一刀,标上序号,只要接收方再根据这个序号拼成最终想要的完整数据就行了
4、TCP流量控制(滑动窗口)和拥塞控制(慢开始,拥塞避免,快重传,快回复)
- 流量控制:让发送方的发送速率不要太快,要让接收方来的及接收
原理是通过确认报文中窗口字段来控制发送方的发送速率,发送方的发送窗口大小不能超过接收方给出窗口大小。 - 拥塞控制:有的时候,不是 接收方的接受能力不够,而是网络不太好,造成了网络拥塞进而导致网络中路由器或链路过载。如果网络出现拥塞,此时发送方继续重传,会导致拥塞程度更高。
拥塞控制的解决办法依然是通过设置一定的窗口大小,只不过,流量控制的窗口大小是 接收方直接告诉发送方 的,而拥塞控制的窗口大小按理说就应该是网络环境主动告诉发送方,但网络环境怎么可能主动告诉 发送方呢?只能 发送方单方面通过试探,不断感知网络环境的好坏,进而确定自己的拥塞窗口的大小,并且动态地在变化
TCP进行拥塞控制的算法主要有:慢开始,拥塞避免,快重传,快恢复
5、TCP粘包、拆包原因和解决办法
UDP是基于报文发送的,从UDP的帧结构可以看出,在UDP首部采用了16bit来指示UDP数据报文的长度,因此在应用层能很好的将不同的数据报文区分开,从而避免粘包和拆包的问题。而TCP是基于字节流的,虽然应用层和TCP传输层之间的数据交互是大小不等的数据块,但是TCP把这些数据块仅仅看成一连串无结构的字节流,没有边界
TCP的发送缓冲区和接收缓冲区
图解粘包拆包的几种形式1
图解粘包拆包的几种形式2
粘包:发送方发送的若干个数据包到接收方接收时粘成一包
发送方原因:
采用了Nagle算法(主要作用:减少网络中报文段的数量),要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发出,产生粘包
接收方原因:
接收数据端的应用层没有及时读取接收缓冲区的数据,将发生粘包
拆包:发送方发送的数据包被拆分成小数据包
原因:
1、要发送的数据大于TCP发送缓冲区大小,发生拆包
2、要发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包
粘包解决办法:
1、在包头部声明包体长度,接收方在接收到数据以后以后读取包头的长度字段,就可以知道每个数据包的实际长度
2、可以在数据包之间设置边界,如在包尾部添加特殊符号如\r\n,但如果数据正文中也有\r\n,则会误判消息边界
3、发送定长包,接收方只要累积接收数据,直到数据长度等于一个定长的数值就将它作为一个消息
6、TCP、UDP报文格式
TCP:
选项:
最常见的可选字段是最长报文大小,又称为 MSS (Maximum Segment Size)。每个连接方通常都在通信的第一个报文段(为建立连接而设置 S Y N标志的那个段)中指明这个选项。它指明本端所能接收的最大长度的报文段。
UDP:
为什么要有伪首部
端口号:
用来表示发送和接受进程。由于 I P层已经把I P数据报分配给TCP或UDP(根据I P首部中协议字段值),因此TCP端口号由TCP来查看,而 UDP端口号由UDP来查看。TCP端口号与UDP端口号是相互独立的。
长度:
UDP长度字段指的是UDP首部和UDP数据的字节长度。该字段的最小值为8字节
检验和:
UDP检验和是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动
HTTP协议
1、HTTP协议1.0、1.1、2.0
HTTP/1.0规定浏览器与服务器只保持短暂连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后马上断开TCP连接,服务器不跟踪每个客户端也不记录每个客户端历史请求
http1.1的长连接和http2.0的多路复用到底有啥区别
HTTP/1.1相比于HTTP/1.0有如下改进:
- 缓存处理
在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略 - 长连接的支持
HTTP/1.1中 connection: keep-alive 是默认开启的。允许在一个TCP连接上传送多个HTTP请求和响应,减少了建立和关闭TCP连接的消耗和延迟 - 请求流水线处理 Pipelining
HTTP/1.1还允许客户端不用等待上一次请求结果返回就可以发出下次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容 - 错误状态码的增多
新增了24个错误状态响应码,丰富的错误码更加明确各个状态
http2协议之多路复用
简析http2协议之多路复用
HTTP/2.0相比于HTTP/1.1有如下改进:
- 新的传输格式Binary Format
2.0使用二进制格式,实现方便且健壮,引入了桢frame和流stream,桢代表最小的数据单位(每个桢会标识出该桢属于哪个流),流是多个桢组成的数据流。1.1仍然使用文本格式 - 多路复用(multiPlexing)
在同一个TCP连接中,同一时刻可以发送多个请求和响应,且不用按照顺序一一对应。之前是同一个连接只能用一次, 如果开启了keep-alive,虽然可以用多次,但是同一时刻只能有一个HTTP请求 - header压缩
前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小
2、HTTP与HTTPS对比
HTTP | HTTPS | |
---|---|---|
端口 | 默认端口80 | 默认端口443 |
安全性 | 明文传输,数据未加密,安全性差 | 传输过程ssl加密,安全性较好 |
效率 | 响应速度快,消耗资源少 | 响应速度慢,消耗资源多,需要用到CA证书 |
应用层协议:HTTPS****************推荐
CA机构签发证书给网站
深入揭秘HTTPS安全问题&连接建立全过程****************推荐
HTTPS链接建立流程
- 客户端发送请求给服务端
- 服务端发送SSL证书给客户端,证书包含有效期,指纹(就是签名),指纹算法,服务端公钥,所有者等信息
- 客户端利用CA公钥解密证书,获取到证书内容,然后将证书内容部分按照指纹算法计算后与指纹比对,一致则使用服务端公钥加密对称秘钥发送给服务端
- 服务端收到后用自己的私钥解密,获取到对称秘钥
- 后面服务端和客户端使用对称秘钥进行信息传输
对称加密算法:
双方持有相同的密钥,且加密速度快,典型对称加密算法:DES,AES
非对称加密算法:
密钥成对出现(私钥、公钥),私钥只有自己知道,不在网络中传输;而公钥可以公开。相比对称加密速度较慢,典型的非对称加密算法有:RSA、DSA
非对称加密相比于对称加密,安全性更高,但有如下2个缺点:
- CPU计算消耗非常大,赛门特克给出实验数据表明:加解密同等数量文件,非对称算法消耗的CPU资源是对称算法的1000倍以上,对称加密的计算量只相当于非对称加密的0.1%
- 非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是2048位,意味着待加密内容不能超过256个字节
所以非对称加解密(极端消耗CPU资源)目前只能用来作对称密钥交换或者CA签名,不适合用来做应用层内容传输的加解密
3、GET与POST对比
GET | POST | |
---|---|---|
可见性 | 数据在URL上,对所有人可见 | 数据不会显示在URL中 |
安全性 | 与post相比,get安全性差,发送的数据是URL的一部分 | 安全,因为参数不会保存在浏览器历史或web服务器日志中 |
数据长度 | 受限制,最长2KB | 无限制 |
缓存 | 能被缓存 | 不能被缓存 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data |
4、HTTP常见响应状态码
100:Continue --- 继续。客户端应继续其请求
200:OK --- 请求成功。一般用于GET和POST请求
301:Moved Permanenty --- 永久重定向
302:Found --- 暂时重定向
400:Bad Request --- 客户端请求的语法错误,服务器无法理解
403:Forbidden --- 服务器理解客户端的请求,但是拒绝执行此行为
404:Not Found --- 服务器无法根据客户端的请求找到资源
500:Internal Server Error --- 服务器内部错误,无法完成请求
502:Bad Gateway --- 网关或者代理服务器尝试执行请求时,从远程服务器收到了无效响应
5、重定向和转发区别
重定向:redirect:
- 地址栏发生变化
- 重定向可以访问其他站点(服务器)的资源
- 重定向是两次请求。不能使用request对象来共享数据
转发:forward:
- 转发地址栏路径不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,可以使用request对象共享数据
6、Cookie和Session区别
- 数据存放位置不同:
cookie数据存放在客户的浏览器上,session数据放在服务器上。 - 安全程度不同:
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。 - 性能使用程度不同:
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。 - 数据存储大小不同:
单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie,而session则存储与服务端,浏览器对其没有限制。 - 会话机制不同:
session会话机制:session会话机制是一种服务器端机制,它使用类似于哈希表(可能还有哈希表)的结构来保存信息。
cookies会话机制:cookie是服务器存储在本地计算机上的小块文本,并随每个请求发送到同一服务器。 Web服务器使用HTTP标头将cookie发送到客户端。在客户端终端,浏览器解析cookie并将其保存为本地文件,该文件自动将来自同一服务器的任何请求绑定到这些cookie
浏览器输入URL全过程
- 浏览器地址栏输入URL
- 浏览器先进行域名解析(DNS解析)查找域名对应的IP地址(从浏览器缓存,路由器缓存,DNS缓存获取,获取不到去ISP获取)
- 浏览器根据获取到的ip地址向服务器发起TCP连接,与浏览器建立TCP三次握手
- 握手成功后,浏览器向服务端发送http请求
- 服务端收到请求,将数据返回给浏览器
- 浏览器读取页面内容并渲染生成DOM树,解析css样式,js交互
网友评论