一、TCP/IP模型与OSI模型的联系
二、TCP、UDP协议的区别
UDP在传送数据之前不需要先建立连接,远地主机在收到UDP报文后,不需要给出任何确认。虽然UDP不提供可靠交付,但在某些情况下UDP确是一种最有效的工作方式(一般用于即时通信),比如:QQ语音、QQ视频、直播等等
TCP提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP不提供广播或多播服务。由于TCP要提供可靠的,面向连接的运输服务(TCP的可靠体现茌TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP—般用于文件传输、发送和接收邮件、远程登录等场景。
三、在浏览器中输入url地址到现实主页经历了哪些过程
详情见:https://www.cnblogs.com/daijinxue/p/6640153.html
https://segmentfault.com/a/1190000006879700
常见的RUL是这样的:http://www.baidu.com,这个域名由三部分组成:协议名、域名、端口号,这里端口是默认所以隐藏。除此之外URL还会包含一些路径、查询和其他片段,例如:https://baike.baidu.com/item/百度/6699。常见的默认端口号如HTTP默认端口80,HTTPS默认端口443。
总体来说分为以下几个过程:
- 1、DNS解析。比如输入www.baidu.com,那么需要先查找域名对应的IP地址,从网址到IP地址的转换就是DNS解析的过程。查找的顺序依次是:浏览器DNS缓存、本地系统DNS缓存、本机hosts文件、DNS服务器
- 2. TCP连接。获取到了服务器的IP地址后,便会开始建立一次连接,这是由TCP协议完成的,主要通过三次握手进行连接。
(1)第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;
(2)第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
(3)第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
- 3. 发送HTTP请求。浏览器向服务器发送HTTP请求,请求报文是由三部分组成: 请求行, 请求报头和请求正文。
(1)请求行
格式如下:Method Request-URL HTTP-Version CRLF
。如:GET index.html HTTP/1.1
。
常用的方法有:GET, POST, PUT, DELETE, OPTIONS, HEAD
。
(2)请求报头
请求报头允许客户端(不一定特指浏览器,有时候也可使用Linux下的CURL命令以及HTTP客户端测试工具等)向服务器传递请求的附加信息和客户端自身的信息。
常见的请求报头有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等
Accept用于指定客户端用于接受哪些类型的信息,Accept-Encoding与Accept类似,它用于指定接受的编码方式。
Connection设置为Keep-alive用于告诉客户端本次HTTP请求结束之后并不需要关闭TCP连接,这样可以使下次HTTP请求使用相同的TCP通道,节省TCP连接建立的时间。
(3)请求正文
当使用POST, PUT等方法时,通常需要客户端向服务器传递数据,这些数据就储存在请求正文中。
在请求包头中有一些与请求正文相关的信息,例如: 现在的Web应用通常采用Rest架构,请求的数据格式一般为json。这时就需要设置Content-Type: application/json。
- 4. 服务器处理请求并返回HTTP报文。这部分对应的就是后端工程师眼中的HTTP。
后端从在固定的端口接收到TCP报文开始,这一部分对应于编程语言中的socket。它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,Web服务器有Tomcat, Jetty和Netty等等。
HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应报文。
(1)状态码
状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:
》1xx:指示信息–表示请求已接收,继续处理。
》2xx:成功–表示请求已被成功接收、理解、接受。
》3xx:重定向–要完成请求必须进行更进一步的操作。
》4xx:客户端错误–请求有语法错误或请求无法实现。
》5xx:服务器端错误–服务器未能实现合法的请求。
(2)响应报头
常见的响应报头字段有: Server, Connection等。
(3)响应报文
服务器返回给浏览器的文本信息,通常HTML, CSS, JS, 图片等文件就放在这一部分。
- 5. 浏览器解析渲染页面
浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。
- 6. 关闭TCP连接或继续保持连接
如果是长连接则继续保持连接。如果是短连接则通过四次挥手关闭TCP连接。
四、各种协议与HTTP协议之间的关系
五、HTTP长连接和短连接
在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如javascript文件、图像 文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。
而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
六、TCP三次握手和四次挥手
1、三次握手的过程
为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。
见:https://www.jianshu.com/p/ae3715d0cf80
第一次握手:客户端发送带有SYN标志的数据包(seq=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到数据包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
2、为什么要三次握手
三次握手的目的是建立可靠的通信倌道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
第一次握手:Client什么都不能确认;Server确认了对方发送正常
第二次握手:Client确认了:自己发送、接收正常,对方发送、接收正常;Server确认了:自己接收正常,对方发送正常
第三次握手:Client确认了:自己发送、接收正常,对方发送、接收正常;Server确认了:自己发送、接收正常, 对方发送接收正常
所以三次握手就能确认双发收发功能都正常,缺一不可。
为什么不使用两次握手
假设使用两次握手,那么
第一次握手,Client发送SYN数据包给服务器,进入SYN_SENT状态;
第二次握手,Server收到数据包后,发送ACK确认包,此时Server认为连接成功建立。
假设,client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。这是一个早已失效的报文,但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送ack包。此时由于Server端认为连接成功建立,并一直等待client发来数据。这样Server端的资源就白白浪费掉了。
如果是三次握手,Server端没有收到Client端的第三次握手确认包,就会认为连接没有建立。
网上流传两次握手可能导致死锁
若是第二次握手Server发送的ACK确认包在网络传输中丢失,那么Client认为连接还未建立成功,将忽略Server发来的任何数据分组,只等待连接确认应答分组。而S在发出的数据分组超时后,重复发送同样的数据分组,这样就形成了死锁。
【但这种说法可能存在问题,因为Client没有收到Server发来的ACK包,可能会再次发送SYN包这样就不存在死锁了】
3、为什么要传回SYN
接收端传回发送端所发送的SYN是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。
SYN是TCP/IP建立连接时使用的握手信号。在客户机和服务器之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,服务器使用SYN-ACK应答表示接收到了这个消息,最后客户机再以 ACK消息响应(Acknowledgement[汉译:确认字符,在数据通信传输中,接收站发给发送站的一种传输控制字符。它表 示确认发来的数据已经接受无误。])。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。
4、传了SYN,为什么还要传ACK
双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要ACK信号来进行验证。
5、TCP四次挥手过程
第一步,客户端主动发起一个FIN标志的数据包(seq=u)给服务器,用来关闭客户端到服务器的数据传送。
**第二步,服务器收到FIN后,发回一个ACK,确认序号为ack=u+1。
第三步,服务器发送FIN标志的数据包(seq=v)给客户端,关闭与客户端的连接。
第四步,客户端发回ACK报文确认,并将确认序号加1。
6、为什么建立连接是三次握手,关闭连接确是四次挥手呢?
(1)建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
(2)关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
四次挥手补充
任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。
举个例子:A和B打电话,通话即将结束后,A说〃我没啥要说的了",B回答"我知道了",但是B可能还会有要说的 话,A不能要求B跟着自己的节奏结束通话,于是B可能又巴拉巴拉说了一通,最后B说"我说完了",A回答〃知道了'这样通话才算结束。
7、为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态?
MSL(Maximum Segment Lifetime):最大报文段生存时间,TCP允许不同的实现可以设置不同的MSL值。
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
8、如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。