slyoy 2019-11-05
从问题切入能帮我们更好地理解晦涩难懂的概念。很多人都知道http协议是基于Tcp协议创造出来的采用文本方式传输(非二进制传输)的应用层协议,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而应用层协议,主要解决如何包装和规范数据。那不经过应用层协议就不能传递数据了吗,当然可以只使用(传输层)TCP/IP协议,但那就像你写了一堆字,却不按语法来写,别人即使看到你的文章,却完全不知道你想表达什么,应用层协议就相当于语言中的语法。
应用层协议有很多,比如HTTP(超文本传输协议)、FTP(文件传输协议)、TELNET(远程登录协议)、SMTP(邮件传输协议)等。现代浏览器默认都支持http协议,也有专门为http协议定制的http服务器。你也可以自己定义应用层协议,只不过所有配套的东西都要自己重新造轮子。
在TCP/IP协议中,要提供可靠的连接服务,需要采用三次握手建立一个可靠连接,为什么建立可靠连接需要三次握手?客户端发起,服务端响应,不是两次握手就可以建立连接了吗?假设没有第三次握手,客户端发出连接请求A,由于网络原因,服务端并没有收到A,于是客户端又发送了连接请求B,并建立了连接,完成通信,断开连接。这时候,服务端突然又收到了A,于是看作是一次新的连接请求,进行第二次握手,由于不存在第三次握手,所以这时已经建立了TCP连接。但实际上客户端并没有发起连接,所以不会传递数据,服务端却一直在等待客户端发数据过来,那么这条连接就会变成一条死连接,造成很大的资源浪费。所以第三次握手的必要性:防止已失效的请求报文段突然又传送到了服务端而造成连接的误判。
断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开,即四次挥手确认断开一个连接。为什么是四次挥手呢,客户端发起,服务端响应,再加一次前面说到的确认,三次就可以完成了呀。
TCP协议是全双工协议,就是说双方都可以同时向对方发送或接收数据。当有一方要关闭连接时,会发送指令告知对方,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭(此时2次挥手了)。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接,接收方发送ACK确认关闭连接(此时4次挥手了)。
最后看一下通信领域常见的全双工、半双工、单工概念:
TCP协议可以提供全双工的数据流传输服务,亦即接收的时候可以发送,发送的时候也可以接收,每个连接都相当于两根并行且双向传输的信号线。
http 1.0是半双工协议,遵循请求-响应模式,就是数据可以在客户端和服务端两个方向上传输,但是不能同时传输。它意味着在同一时刻,只有一个方向上的数据传送,每个连接都相当于只有一根可以双向传输的信号线。
http1.1也是半双工协议,依然遵循请求-响应模式,但引入了管道机制,建立了长连接和多路复用,可先后发送多个http请求,不用等待回复,回复按顺序一个一个回复。但是客户端在未收到之前所发出所有请求的响应之前,将会阻塞后面的请求(排队等待),比如谷歌浏览器最多同时允许同域名下6个并发请求,如果该6个请求一直没有响应,将会引起后续所有请求的阻塞。
http2.0(未普及)是全双工协议,依然遵循请求-响应模式,但客户端发送多个请求和服务端给出多个响应的顺序不受限制,这样既避免了堵塞,又能更快获取响应。在复用同一个TCP连接时,服务器同时(或先后)收到了A、B两个请求,先回应A请求,但由于处理过程非常耗时,于是就发送A请求已经处理好的部分, 接着回应B请求,完成后,再发送A请求剩下的部分。
长连接,指建立一个TCP连接后,可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持。 建立连接后,在断开之前,后续每次交互数据包不需要再经过三次握手四次挥手过程。常见头信息中Connection:keep-alive
短连接,是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,每次交互数据都需要经过握手和挥手的繁琐过程,一般银行都使用短连接。常见头信息中Connection:close
<完>