因为HTTP是一个基于TCP的协议,而TCP是一种可靠的传输层协议.
建立TCP连接时会发生:三次握手(three-way handshake)
firefox > nginx [SYN] 在么
nginx > firefox [SYN, ACK] 在
firefox > nginx [ACK] 知道了
关闭TCP连接时会发生:四次挥手(four-way handshake)
firefox > nginx [FIN] 我要关闭连接了
nginx > firefox [ACK] 知道了,等我发完包先
nginx > firefox [FIN] 我也关闭连接了
firefox > nginx [ACK] 好的,知道了
几个报文的标识的解释:
SYN: synchronization(同步)
ACK: acknowledgement(确认:告知已收到)
FIN: finish(结束)
在HTTP/1.1中,keep-alive能够复用TCP连接,减少TCP三次握手的次数,从而提升性能.
结合到PHP编程中,拿Swoole引擎内置的异步HTTP服务器来说说:
调用 $res->end() 将结束HTTP请求,但不会关闭HTTP连接,因为Swoole支持keep-alive.
调用 $serv->close($res->fd) 将关闭HTTP连接.
这种ack确认机制在应用逻辑开发上也是很有用的,比如你用PHP+Swoole开发一个即时通讯软件,要确保不丢消息,要做到:
A <=> Server <=> B
A发送消息给B后,如果A在指定时间内没有收到Server的消息通知,那么A就要超时重发. 正常情况下,Server收到A的消息后推送给B,B收到消息后通知Server,Server再通知A. 当然,A的超时重发可能会导致B收到重复的消息,所以B接受消息时要进行去重.
如果要考察HTTP,我觉得问下HTTP请求/响应报文的组成可能会更好.
HTTP请求报文组成:请求行+请求头+请求体
HTTP响应报文组成:响应行+响应头+响应体
请求行: 请求方法(HEAD/GET/POST) + 请求URL + HTTP协议版本
响应行: HTTP协议版本 + 状态码 + 状态码描述
请求头: 比如客户端的Cookie和User-Agent就放在这里.
响应头: 比如服务器的Set-Cookie和Server信息就放在这里.
请求体: 比如客户端POST的数据就放在这里(对比:GET的数据放在请求行的URL里).
响应体: 比如服务器返回的HTML和JSON数据就放在这里.
curl -I http://mysite
curl这样发起的HTTP请求的请求方法(request_method)就是HEAD,可以这样查看:
PHP-FPM: header("请求方法: $_SERVER['REQUEST_METHOD']");
Swoole: $res->header('请求方法', $req->server['request_method']);
先我们知道HTTP协议通常承载于TCP协议之上,HTTPS承载于TLS或SSL协议层之上
通过上面这张图我们能够知道。
在Http工作之前,Web浏览器通过网络和Web服务器建立链连接,该连接是通过Tcp来完成的,该协议和Ip共同组成了Internet,即著名的Tcp/Ip协议族,Http是比Tcp更高的应用层协议,一般Tcp接口的端口好是80。
TCP 被称为“面向连接”的传输层协议。关于它的具体细节,就不展开了。你只需知道:传输层主要有两个协议,分别是 TCP 和 UDP。TCP 比 UDP 更可靠。你可以把 TCP 协议想象成某个水管,发送端这头进水,接收端那头就出水。并且 TCP 协议能够确保,先发送的数据先到达(与之相反,UDP 不保证这点)
一、TCP简介
TCP(Transmission Control Protocol) 传输控制协议
TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:
位码即tcp标志位,有6种标示:SYN(建立联机) ACK(确认) PSH(传送) FIN(结束) RST(重置) URG(紧急)
Sequence number(顺序号码) Acknowledge number(确认号码)
二、TCP三次握手
第一次握手:客户端发送了一个带有SYN(建立连接)的Tcp报文到服务器,这个三次握手中的开始。表示客户端想要和服务端建立连接。
第二次握手:服务端接收到客户端的请求,返回客户端报文,这个报文带有SYN(建立连接)和ACK(确认)标志,询问客户端是否准备好。
第三次握手:.客户端再次响应服务端一个ACK(确认),表示我已经准备好。
思考:为什么要三次握手呢,有人说两次握手就好了
举一个例子:已失效的连接请求报文段,
client发送了第一个连接的请求报文,但是由于网络不好,这个请求没有立即到达服务端,而是在某个网络节点中滞留了,直到某个时间才到达server,本来这已经是一个失效的报文,但是server端接收到这个请求报文后,还是会想client发出确认的报文,表示同意连接。假如不采用三次握手,那么只要server发出确认,新的建立就连接了,但其实这个请求是失效的请求,client是不会理睬server的确认信息,也不会向服务端发送确认的请求,但是server认为新的连接已经建立起来了,并一直等待client发来数据,这样,server的很多资源就没白白浪费掉了,采用三次握手就是为了防止这种情况的发生,server会因为收不到确认的报文,就知道client并没有建立连接。这就是三次握手的作用。
三、TCP的四次挥手
第一次握手:TCP发送一个FIN(结束),用来关闭客户到服务端的连接。
第二次握手:服务端收到这个FIN,他发回一个ACK(确认),确认收到序号为收到序号+1,和SYN一样,一个FIN将占用一个序号。
第三次握手:服务端发送一个FIN(结束)到客户端,服务端关闭客户端的连接。
第四次握手:客户端发送ACK(确认)报文确认,并将确认的序号+1,这样关闭完成。
思考:那么为什么是4次挥手呢?
可能有人会有疑问,tcp我握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢.
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
四、TCP和UDP的区别
我这里简单列举几个,因为我还没有研究UDP这个协议。
1.基于连接与无连接;(UDP是非连接)
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单
4.流模式与数据报模式 ;(TCP是流模式)
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
© 著作权归作者所有
分享
阿锋zxf
粉丝 8
博文 111
码字总数 127463
作品 0
深圳
程序员
计算机网络体系结构: OSI(Open System Interconnection)开放式系统互联: 理念完整,复杂不实用 TCP/IP(Transmission Control Protocol/Internet Protoco) : 因特网核心协议 五层体系结构:...
HeroHY
2017/07/25
3
0
本文希望以简单易懂的形式解释下这个问题,其具体的发包数据、过程等还请自行Google。纯属个人观点,如有不妥,还请各位看官指教。 TCP协议是一种面向连接的、可靠的、基于字节流的传输层通信...
河图再现
05/17
0
0
1、前言 尽管TCP和UDP都使用相同的网络层(IP),TCP却向应用层提供与UDP完全不同的服务。TCP提供一种面向连接的、可靠的字节流服务。 面向连接意味着两个使用TCP的应用(通常是一个客户和一...
JackJiang-
2016/09/26
596
2
TCP连接管理 TCP运输连接有3个阶段, 即: 连接建立,数据传送和连接释放。 1. TCP的连接建立(3次握手) TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户(client), 而被...
xiaoxlm
07/29
0
0
恋爱时 连接时客户端说:SYN(约吗?) 服务器说:SYN+ACK(约啊,一起) 接着客户端说:ACK(好的) 热恋时 传输了n个字节的数据之后,开始分手流程 分手时 客户端说:FIN(分手了
来源:CSDN
作者:qq_32444825
链接:https://blog.csdn.net/qq_32444825/article/details/82584824