TCP
TCP和UDP区别
连接性:
- tcp:面向连接
- udp: 无连接
可靠性:
- tcp:可靠(无差错、不丢失、不重复、且按照顺序到达)
- udp:不可靠(尽最大努力交付)
传输效率:
- tcp:慢
- udp:快
引申问题:TCP是如何保证可靠性的?
答:无差错、不丢失、不重复、且按照顺序到达
原理:在TCP连接中 ,数据流必须以正确的顺序送达到对方。TCP的可靠性是通过顺序号和确认来实现的,
即seq(序列号)、ack(确认序列号)
TCP可靠性实现:
拥塞窗口
发送方为一个动态变化的窗口叫做拥塞窗口,拥塞窗口的大小取决于网络的拥塞程度。发送方让自己的发送窗口=拥塞窗口,但是发送窗口不是一直等于拥塞窗口的,在网络情况好的时候,拥塞窗口不断的增加,发送方的窗口自然也随着增加,但是接受方的接受能力有限,在发送方的窗口达到某个大小时就不在发生变化了。
发送方如果知道网络拥塞了呢?发送方发送一些报文段时,如果发送方没有在时间间隔内收到接收方的确认报文段,则就可以人为网络出现了拥塞。
慢启动
主机开发发送数据报时,如果立即将大量的数据注入到网络中,可能会出现网络的拥塞。慢启动算法就是在主机刚开始发送数据报的时候先探测一下网络的状况,如果网络状况良好,发送方每发送一次文段都能正确的接受确认报文段。那么就从小到大的增加拥塞窗口的大小,即增加发送窗口的大小。
例子:开始发送方先设置cwnd(拥塞窗口)=1,发送第一个报文段M1,接收方接收到M1后,发送方接收到接收方的确认后,把cwnd增加到2,接着发送方发送M2、M3,发送方接收到接收方发送的确认后cwnd增加到4,慢启动算法每经过一个传输轮次(认为发送方都成功接收接收方的确认),拥塞窗口cwnd就加倍。
拥塞避免
为了防止cwnd增加过快而导致网络拥塞,所以需要设置一个慢开始门限ssthresh状态变量(我也不知道这个到底是什么,就认为他是一个拥塞控制的标识),它的用法:
当cwnd < ssthresh,使用慢启动算法,
当cwnd > ssthresh,使用拥塞控制算法,停用慢启动算法。
当cwnd = ssthresh,这两个算法都可以。
拥塞避免的思路:是让cwnd缓慢的增加而不是加倍的增长,每经历过一次往返时间就使cwnd增加1,而不是加倍,这样使cwnd缓慢的增长,比慢启动要慢的多。
无论是慢启动算法还是拥塞避免算法,只要判断网络出现拥塞,就要把慢启动开始门限(ssthresh)设置为设置为发送窗口的一半(>=2),cwnd(拥塞窗口)设置为1,然后在使用慢启动算法,这样做的目的能迅速的减少主机向网络中传输数据,使发生拥塞的路由器能够把队列中堆积的分组处理完毕。拥塞窗口是按照线性的规律增长,比慢启动算法拥塞窗口增长块的多。
实例:
- TCP连接进行初始化的时候,cwnd=1,ssthresh=16。
- 在慢启动算法开始时,cwnd的初始值是1,每次发送方收到一个ACK拥塞窗口就增加1,当ssthresh =cwnd时,就启动拥塞控制算法,拥塞窗口按照规律增长,
- 当cwnd=24时,网络出现超时,发送方收不到确认ACK,此时设置ssthresh=12,(二分之一cwnd),设置cwnd=1,然后开始慢启动算法,当cwnd=ssthresh=12,慢启动算法变为拥塞控制算法,cwnd按照线性的速度进行增长。
AIMD(加法增大乘法减小)
乘法减小:无论在慢启动阶段还是在拥塞控制阶段,只要网络出现超时,就是将cwnd置为1,ssthresh置为cwnd的一半,然后开始执行慢启动算法(cwnd<ssthresh)。
加法增大:当网络频发出现超时情况时,ssthresh就下降的很快,为了减少注入到网络中的分组数,而加法增大是指执行拥塞避免算法后,是拥塞窗口缓慢的增大,以防止网络过早出现拥塞。
这两个结合起来就是AIMD算法,是使用最广泛的算法。拥塞避免算法不能够完全的避免网络拥塞,通过控制拥塞窗口的大小只能使网络不易出现拥塞。
快重传
快重传算法要求首先接收方收到一个失序的报文段后就立刻发出重复确认,而不要等待自己发送数据时才进行捎带确认。接收方成功的接受了发送方发送来的M1、M2并且分别给发送了ACK,现在接收方没有收到M3,而接收到了M4,显然接收方不能确认M4,因为M4是失序的报文段。如果根据可靠性传输原理接收方什么都不做,但是按照快速重传算法,在收到M4、M5等报文段的时候,不断重复的向发送方发送M2的ACK,如果接收方一连收到三个重复的ACK,那么发送方不必等待重传计时器到期,由于发送方尽早重传未被确认的报文段。
快恢复
当发送发连续接收到三个确认时,就执行乘法减小算法,把慢启动开始门限(ssthresh)减半,但是接下来并不执行慢开始算法。
此时不执行慢启动算法,而是把cwnd设置为ssthresh的一半, 然后执行拥塞避免算法,使拥塞窗口缓慢增大。
简述TCP的三次握手、四次挥手,为什么要三次握手?为什么client会进入TIME_WAIT?
TCP的三次握手:
序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。
确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
同步SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接
(1)client端发送连接请求:SYN=1(建立新连接),seq=x
(2)server端接收请求并返回确认报文:SYN=1(建立新连接),ACK=1(ack有效),ack=x+1,seq=y
(3)client接收到确认报文,再次发送确认消息:ACK=1(ack有效),seq=x+1(client上一条请求seq+1),ack=y+1
(4)server端收到确认后,连接建立
TCP的四次挥手:
(1)client端发送连接释放报文:FIN=1,seq=u
(2)server收到之后发出确认,此时TCP属于半关闭状态,server能向client发送数据反之不能:ACK=1,seq=v ack=u+1
(3)当server处理完毕后,发送连接释放报文:FIN=1,ACK=1,seq=w,ack=u+1
(4)client收到后发出确认,进入TIME-WAIT状态,等来2MSL(最大报文存活时间)后释放连接:ACK=1,seq=u+1,ack=w+1
(5)server收到client的确认后释放连接
为什么要进行三次握手?
第三次握手时为了防止失效的连接请求到达服务器,让服务器错误打开连接。
客户端发送的连接请求如果在网络中滞留,那么就会隔很长时间才能收到服务器的连接确认。客户端等待一个超时重传时间后,就会重新发起请求。但是这个滞留的连接请求最后还是会到达服务器,如果不进行第三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
为什么会有TIME_WAIT?
客户端接收到服务器的FIN报文后进入TIME_WAIT状态而不是CLOSED,还需要等待2MSL,理由:
确保最后一个确认报文能够到达。如果server端没收到client端发来的确认报文,那么就会重新发送连接释放请求报文。
为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
【问题】如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
HTTP
GET和POST的区别?
首先,GET和POST都是HTTP协议中的两种发送请求的方法,由于HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP。GET和POST能做的事情是一样一样的。如果给GET加上request body,活着给POST带上url参数,技术上是完全行的通的。也就是说,GET和POST在本质上没什么区别。
但是如果真的一点区别都没有,那么这个问题也就不存在了,所以,两者之间最重大的区别就是
GET产生一个TCP数据包;POST产生两个TCP数据包。
具体点说来就是:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
- GET与POST都有自己的语义,不能随便混用。
- 如果网络环境好的话,发一次包的时间和发两次包的时间差别基本可以无视。如果网络环境差的话,两次包的TCP在验证数据包完整性上,有非常大的优点。
- 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
- 另外,w3schools上面的参考答案也是可以酌情说一些的:
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。 - GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
Http与Https的区别:
- HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
- HTTP 是不安全的,而 HTTPS 是安全的
- HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
- 在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
- HTTP 无法加密,而HTTPS 对传输的数据进行加密
- HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书
什么是Http协议无状态协议?怎么解决Http协议无状态协议?
无状态协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息
也就是说,当客户端一次HTTP请求完成以后,客户端再发送一次HTTP请求,HTTP并不知道当前客户端是一个”老用户“。
可以使用Cookie来解决无状态的问题,Cookie就相当于一个通行证,第一次访问的时候给客户端发送一个Cookie,当客户端再次来的时候,拿着Cookie(通行证),那么服务器就知道这个是”老用户“。
一次完整的HTTP请求所经历的7个步骤
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
建立TCP连接
在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建 Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则, 只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。Web浏览器向Web服务器发送请求行
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET /sample/hello.jsp HTTP/1.1。Web浏览器发送请求头
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。Web服务器应答
客户机向服务器发出请求后,服务器会客户机回送应答, HTTP/1.1 200 OK ,应答的第一部分是协议的版本号和应答状态码。Web服务器发送应答头
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。
Web服务器向浏览器发送数据Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据。
7.Web服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:
Connection:keep-alive
Http1.x
- 缺陷:线程阻塞,在同一时间,同一域名的请求有一定数量限制,超过限制数目的请求会被阻塞
http1.0
- 缺陷:浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接(TCP连接的新建成本很高,因为需要客户端和服务器三次握手),服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求;
解决方案:
添加头信息——非标准的Connection字段Connection: keep-alive
http1.1:
- 改进点:
持久连接
引入了持久连接,即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive(对于同一个域名,大多数浏览器允许同时建立6个持久连接)管道机制
即在同一个TCP连接里面,客户端可以同时发送多个请求。分块传输编码
即服务端没产生一块数据,就发送一块,采用”流模式”而取代”缓存模式”。新增请求方式
PUT:请求服务器存储一个资源;
DELETE:请求服务器删除标识的资源;
OPTIONS:请求查询服务器的性能,或者查询与资源相关的选项和需求;
TRACE:请求服务器回送收到的请求信息,主要用于测试或诊断;
CONNECT:保留将来使用
- 缺点:
虽然允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个请求,才会接着处理下一个请求。如果前面的处理特别慢,后面就会有许多请求排队等着。这将导致“队头堵塞”
避免方式:一是减少请求数,二是同时多开持久连接
HTTP/2.0
- 特点:
- 采用二进制格式而非文本格式;
- 完全多路复用,而非有序并阻塞的、只需一个连接即可实现并行;
- 使用报头压缩,降低开销
- 服务器推送
- 二进制协议
- HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”:头信息帧和数据帧。
- 二进制协议解析起来更高效、“线上”更紧凑,更重要的是错误更少。
- 完全多路复用
- HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了”队头堵塞”。
- 报头压缩
- HTTP 协议是没有状态,导致每次请求都必须附上所有信息。所以,请求的很多头字段都是重复的,比如Cookie,一样的内容每次请求都必须附带,这会浪费很多带宽,也影响速度。
- 对于相同的头部,不必再通过请求发送,只需发送一次;
- HTTP/2 对这一点做了优化,引入了头信息压缩机制;
- 一方面,头信息使用gzip或compress压缩后再发送;
- 另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,产生一个索引号,之后就不发送同样字段了,只需发送索引号。
- 服务器推送
- HTTP/2 允许服务器未经请求,主动向客户端发送资源;
- 通过推送那些服务器任务客户端将会需要的内容到客户端的缓存中,避免往返的延迟