什么是有状态协议,什么是无状态协议;协议有无状态和协议是长连接还短连接有关系?
之前一直对HTTP协议和TCP协议的内幕不清不楚,前段时间想到这块,也看了些网上大牛们的文章;在这里将自己的理解写出来,一来做个笔记二来也是借这个机会把自己的理解梳理一下.
协议状态
从学习编程开始我们都知道http是无状态的,那么什么是无状态呢?
官方的说法是对事务处理没有记忆能力。而我个人的理解是,下次请求不知道上次请求的信息:它不知道上次请求是成功还是失败,不知道上次请求的内容是什么。即每次请求之间没有建立关联关系,HTTP显然是无状态的(使用session和cookie建立的会话不是HTTP协议的一部分)。
TCP是有状态的,这个从它的处理模式中能看出来。
TCP协议在发送数据之前要进行三次握手建立可靠连接,之后才开始发送数据,而且接收端在收到请求之后会发送回执告诉发送端已经收到了数据;发送端接收到回执之后才继续发送数据,如果未收到回执发送端会认为数据发送失败了,会重新发送这部分数据。既然TCP下一次发送数据时是知道上次发送了什么数据,状态如何,显然tcp是有状态的协议。
既然说到这里了我就顺便说说TCP的3次握手:
下表面我以发短信为喻说明下:
第一次张三发给李四:李四,哥要给你发个消息可以不?
第二次李四发给张三:三哥,我这没问题
第三次张三再发给李四:好,我知道啦,开始发了
请求次数 | 张三 | 李四 |
---|---|---|
第1 次 | 无 | 无 |
第2次 | 发送能力 | 接收能力,发送能力 |
第3次 | 接收能力 |
三次握手才证了双方都有发送数据和接收数据的能力,这样连接才算是可靠连接,缺少任意一次都不能证明。
长连接和短连接:
http1.0之前http只有短连接,1.1之后才有长连接。
HTTP协议的传输层使用的是TCP传输协议,发送数据之前要建立TCP连接。短连接是指每次发送请求都建立新的TCP连接,发送完就关闭;长连接是在发送完请求后不关闭连接而是隔断时间就发个数据包,以保持连接不被关闭(即使不显式的关闭连接,超时时间到时也会自动关闭)。
长连接缺点:对服务器资源的消耗比较大,而且不够安全。
优点:减少连接开销。
我们区分协议有状态还是没状态是看它有没有和上次请求建立关系,而和它是长连接和短连接没有关系。
疑问
既然Http的传输层协议是TCP,而且tcp是有状态的,那么为什么HTTP是无状态的?如果说在短连接里两次请求间不是一个TCP连接所以无状态,那么长连接里用的是同一个连接,怎么还是无状态呢?
之前一直有一个错误认识:一个TCP没关闭之前,它里面传输的数据包都是有联系的。这样想是不对的:
我以一次Http请求报文来说明下,http报文发送到TCP层之后TCP协议会将这一个HTTP报文拆分为10个TCP报文(IP包的大小不是无限的),对Http来说这10个TCP包是一个请求,但是对TCP来说是10个请求。假如这是一个长连接,那么我再发个Http请求,TCP把它拆为20个TCP包;显然这20个TCP包和之前的10个TCP包是没有任何关系的,但是一个HTTP包拆分出来的TCP包之间显然是有关联的(这个拆分是由TCP协议的机制来做的,我门自己拆分的不行),可见TCP的有状态也是狭隘的,狭义的。