http的“无连接”指的是_http协议无状态中的 quot;状态quot; 到底指的是什么?...

  引子:

  最近在好好了解http,发现对介绍http的第一句话【http协议是无状态的,无连接的】就无法理解了:无状态的【状态】到底指的是什么?!

  找了很多资料不仅没有发现有一针见血正面回答这个问题的,而且有些解释还充斥了各种错误,看着看着就觉得心里憋着一股浊气吐不出来

  于是在看了很多资料之后,我一口吐出浊气,大声正面提出这个问题:http协议无状态中的【状态】到底指的是什么?!

  然后开始不断探索解决这个问题。。。

  最终很高兴的是我找到了让人满意的答案,先卖个关子,各位如果着急可以直接拉到最下查看

f3f7d78a7c573777309d4152c33d88a8.png

  正文:http协议无状态中的【状态】到底指的是什么?!

  先来看这句话的另外两个概念:(标准的http协议是无状态的,无连接的)

  1、标准的http协议指的是不包括cookies, session,application的http协议,他们都不属于标准协议,虽然各种网络应用提供商,实现语言、web容器等,都默认支持它

  2、无连接指的是什么

    1、每一个访问都是无连接,服务器挨个处理访问队列里的访问,处理完一个就关闭连接,这事儿就完了,然后处理下一个新的。

    2、无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。

  对于【无状态】,我看到很多隔着一层磨砂玻璃一样的模糊说法(官方或者教程里的说法),看着非常难受(但其实算是对的)(后来我发现我为什么觉得它看着难受了,因为他们引入了很多新的,而且明显是一个可能用在很多地方的广义名词,这些词最大的作用就是,混淆概念,下面我标注了)

  1、协议对于事务处理没有记忆能力【事物处理】【记忆能力】

  2、对同一个url请求没有上下文关系【上下文关系】

  3、每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况【无直接联系】【受直接影响】

  4、服务器中没有保存客户端的状态,客户端必须每次带上自己的状态去请求服务器【状态】

  我必须得到确切而具体的解释!

  这几点给了我下一步思考的方向:

  1、【服务器中没有保存客户端的状态,客户端必须每次带上自己的状态去请求服务器 】这里的客户端的状态是不是确切地指服务器没有保存客户的信息呢?但显然不是啊

  2、【HTTP无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品】我对此质疑为什么无状态就不能实现购物车呢?服务器就不能存储东西了么?

  3、【 每次的请求都是独立的,与和是无直接关系的】我觉得这个说法比较靠谱,但是所谓的不同请求间的没有关系,是指的请求内容没有关系,还是只是指请求本身没有关系?

    1、请求内容没有关系只可能是服务器上不存有用户数据才可能啊,但是显然是存有的啊

    2、请求本身没有关系,这又有什么意义呢,每一次的请求有什么价值?

  根据这个方向我做了一个模拟访问实验:假如没有cookie没有session,只有http的时候,那当一个注册用户访问这个购物网站的时候,会发生这些事情:

  1、前提情况:

    1、服务器肯定为每个注册用户建立了数据表,记录用户的数据

    2、http是无连接的

  2、第一步需要登录

    1、用户通过http把用户的用户名和密码发送给服务器,服务器把他们跟自己存有的用户资料对比,如果一致,则返回信息登录成功

  3、然后用户点击某一商品页

    1、这个动作相当于输入一个商品页的网址

    2、假如商品页比较机密不对外公开,需要是用户才能访问

    3、而虽然http能传送用户名和密码,而且刚才也输入了,还验证成功了,但是因为服务器既不会记得你登录的状态,你的客户端也不会存储你刚才输入的用户名和密码

    4、所以因为这一次访问因为无法确定你的身份,只能访问失败。这时候如果要解决这个问题,而且没有cookie没有session,那就只能你在访问网址的同时继续带上你的用户名和密码(继续输入咯)其实就像我现在的APP一样

  4、假设上一步的问题解决了,就是每次访问的时候都会手动输入用户名和密码,然后现在的情况是:你已经选了几件商品在你的购物车中,你想再添加一件商品,于是你点击某个商品旁边的加号

    1、这个动作也相当于输入一个网址,网址的内容是发送一个请求,往你的购物车中加入这个商品

    2、系统首先用你传来的用户名和密码验证你的身份,然后访问你的数据库,在其中的购物车属性下加一条数据,就是这个商品的数据

    3、操作结束后,返回操作成功,并结束访问

  5、OK,实验结束,看似没有cookie没有session也能凑合解决问题,其实两个操作都有很大的问题

    1、你每访问一次需要权限的内容都需要在客户端输入用户名和密码,这一项的繁琐就不必赘述了

    2、你的每一次操作都要与系统底层的数据库进行交互。多次少量的访问存在非常大的性能浪费。非常容易就能想到肯定是一次大量的操作更加有效率,于是就想到了缓存区

    3、你的非重要琐碎数据也被写进数据库中,跟你的主要数据放在一起。一次次添加和删除购物车其实只是跟你这次浏览,或者叫这次会话有关,是临时的数据,跟用户的主要信息无关,它们没什么价值,纯粹的冗余数据(不排除现在有的公司觉得这种数据也有非常大的价值可以让它们巧妙的利用),用什么存放这些临时的数据,我们也很容易想到缓存区

  经过这个模拟访问实验,结合前面的思考方向,我们知道了三点:

  1、服务器上肯定存有用户的数据,你提交的增删改查它也能够处理,所以这句话中【服务器中没有保存客户端的状态】的状态并不是指用户的数据,我们的猜测不对

  2、我们的质疑对了,无状态能实现购物车,可以通过服务器上存有的用户数据来实现

  3、但是,使用上面这种方式实现购物车,存在三个比较大的问题。由此,我们不禁会想,这三个问题的解决是不是跟我们不确切了解的【状态】一词有关?于是,接下来我们来通过解决这三个问题来把【状态】的意义探寻下去

  由上所述,我们可以在http的基础上增加一些机制来解决上面出现的三个问题

  1、在用户端增加一个记录本是非常有必要的,正好官方加入的cookie机制跟这个一样,它的用处也确实是上面讨论的那样,一般就是用来标识访问者的身份

  2、在服务器增加一个缓存区能同时解决后两个问题

    1、有了这个缓存区作为一个数据缓冲,就不用一次次地访问数据库,浪费大量计算机资源,而是在最后统一归入数据库

    2、有了这个缓存区,你就不用把临时的数据放到数据库中了,只需要在你们交流告一段落之后,再把数据整理,把有用的数据归入数据库

  3、这里就自然引申出了一个重要的概念:会话,它作为一个缓冲存储区被从数据库中分离出来,理由并不生硬,它有其独特的重要且不可替代的作用。这个东西恰好跟官方加入的session机制一样

    1、另外说一个非常具有迷惑性的容易让人对session的主要作用产生偏离的理解:认为session存在的价值就是给访问者分配一个sessionID代替用户名和密码,

    2、为什么非常具有迷惑性,因为session确实做了这件事,而且也起到了很大的作用,所以它是对的,但是只对一半,而且没有涉及问题的本质,这种情况是最危险的(看似很有说服力,把你说服了,所以你很难有动力继续找下去,但是真实情况跟它有偏差,但是偏差不大,所以又很难把你说服回来,只有隐隐的不对劲,这个时候你离真实最近,也离真实最远)

    3、那就顺便说说它为什么是对的,也就是用session做的另一件有用的事:

      1、给每个session一个ID,一方面用来方便自己查询,另一方面把这个ID给用户,用户下一次访问的时候就可以不用用户名和密码,而是直接使用这个ID来表明自己的身份

      2、首先,这个ID安全吗?这个ID比直接传用户名和密码安全吗?

        1、你很容易会想到,本来用户名和密码的组合还特地设置地比较复杂,你这换一组数字就代替了,是不是太不安全了?

        2、我们知道http协议本身是完全不加密的,如果使用用户名和密码,第一次访问是放在http头中,后边自动保存了密码就会放在cookie中,这些都完全没有加密,它的安全性基本为0,就是裸奔了,只要被窃取,那就丢失了

        3、所以,就这个意义来讲,sessionID的安全性跟使用用户名和密码没什么区别

        4、但是其实,虽然http本身不能加密,但是有些软件什么的,能在应用层面手动给你加密,比如QQ就会使用户名密码加临时验证码联合哈希,sessionID加一个时间戳简单加密也是非常常用的方法

        5、而且因为sessionID本身有有效期,即使丢了,也可能很快失效,造成的损失可能没那么大,而用户名跟密码丢了,那就大了

        6、所以总结就是:不严格加密的sessionID和用户名和密码一样,都不太安全。但是相比较来说,sessionID要安全一些。而使用https是完全安全的。

      3、然后,使用sessionID有哪些好处

        1、方便直接根据ID查询用户对应的session

        2、加密的时候计算量小

        3、安全性不会降低,甚至还更高一些

  OK,通过独立地解决纯http机制会产生的问题,我们探讨了cookie和session机制的本质。而且想到:【使用http协议,服务器中不会保存客户端的状态】所产生的问题通过增加cookie和session机制解决了,是不是就意味着这个【状态】跟cookie和session的关系非常紧密?所以这个无状态指的是【没有对 本次会话 设置一个缓存区,记录这次会话的状态,缓存区包括服务器端和用户端】但好像还是没有点破关键(主要是觉得跟前面那些官方对状态的说法不太吻合,甚至没有对应关系)

  忽然我想到一个问题:一个有状态的http是什么样的?

  1、很难直接想象有状态的http是什么样,因为http这种机制是天然无状态的

  2、那就类比一下吧,另一个天然有状态的机制叫TCP。如果有状态的意思是它的每次请求是有联系的,那么有状态的TCP的样子是:假如一份数据分了三份TCP包发送,那这个包上面会标明这是第几个包,会标明这个包跟那几个包是有联系的,有什么联系

  3、但好像这个有状态的TCP跟我们想要的有状态的HTTP没有关系,因为即使每次http请求之间互相有联系,它也不能解决上面提到的http无状态的问题

  4、诶,等等,好像能类比:

    1、假如每个http连接都有一个签名,于是第一次登陆成功之后,服务器就知道了这个签名是允许登陆的,于是之后所有同样签名的http连接都能登陆,这里利用了同一个用户发出的http连接之间的同主人关系,这里解决了一个保持登录状态的问题

    2、同样,来尝试利用这个【每次http请求之间互相有联系】来解决上面碰到的那个问题【每一次操作都要与系统底层的数据库进行交互】,但想了半天确实无法进行下去

    3、不过我灵机一动,从另一个角度来想,好像解决了这个问题:

      1、只有【每次http请求之间互相有联系】这个条件,无法解决【每一次操作都要与系统底层的数据库进行交互】

      2、因为很明显,要解决【每一次操作都要与系统底层的数据库进行交互】就必须在服务器端开辟一块缓存区

      3、不过如果你思考一下如何实现【每次http请求之间互相有联系】,你就会发现,它也需要在服务器端开辟一块缓存区

      4、所以【在服务器端开辟一块缓存区】才是真正的条件,也就是说,它确实等价于【有状态】

      5、而且我也找到了这个【在服务器端开辟一块缓存区】的条件跟前面那些官方对状态的说法对应的点,那就是:通过在服务器端开辟一块缓存区,存储、记忆、共享一些临时数据,你就可以:

        1、协议对于事务处理有记忆能力【事物处理】【记忆能力】

        2、对同一个url请求有上下文关系【上下文关系】

        3、每次的请求都是不独立的,它的执行情况和结果与前面的请求和之后的请求是直接关系的【不独立】【直接关系】

        4、服务器中保存客户端的状态【状态】

      6、所以,这个状态,加上前面说的客户端也有cookie,就是指,客户端和服务器在临时会话中产生的数据!而前面也说道了,使用缓存区保存临时会话中的数据是多么重要

        1、所以状态不仅包括不同URL访问之间的关系,还有对其他URL访问的数据记录,还有一些其他的东西,所以更确切地说,状态应该是【实现了这些东西所凭借的后面的缓存空间】中的客户的临时数据

        2、cookie和session应该是完全实现了有状态这个功能

  一种常见的对状态的误解:

  1、有人在解释HTTP的无状态时,把它跟有连接对立,说是两种方式,也就是如果想不无状态,就必须有连接,但其实不然

  2、有连接和无连接以及之后的Keep-Alive都是指TCP连接

  3、有状态和无状态可以指TCP也可以指HTTP

  4、TCP一直有状态,HTTP一直无状态,但是应用为了有状态,就给HTTP加了cookie和session机制,让使用http的应用也能有状态,但http还是无状态

  5、开始TCP是有连接,后来TCP无连接,再后来也就是现在TCP是Keep-Alive,有点像有连接

作者:赛艇队长

https://www.cnblogs.com/bellkosmos/p/5237146.html

e2f01802ecfb8cc2fe45d2fb3ea72506.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

个人日志-7.4

姓名 刘鑫 时间 2016.7.4 学习内容 完善需求分析报告。撰写数据库设计说明书。初步安排计划概要设计说明书。调整项目开发计划说明书。 所遇问题 无 解决方案 无 转载于:https://www.cnblogs.com/liuxin13070013/p/5641967.html

STM32F1笔记(五)外部中断EXTI

STM32的每个IO都可以作为外部中断的中断输入口。 STM32F103的中断控制器支持19个外部中断/事件请求。每个中断设有状态为,每个中断/事件都有独立的触发和屏蔽设置。 STM32F103的19个外部中断为: EXTI线0~15:对应外部IO口的输入中断。 EXT…

STM32F1笔记(六)独立看门狗IWDG

STM32F1内置了两个看门狗,独立看门狗IWDG和窗口看门狗WWDG,可以用来检测和解决由软件错误引起的故障。 IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。WWDG最适合那些要求…

在JSF 2中对定制验证器进行参数化

在JSF 2中编写自定义验证器并不复杂。 您实现Validator接口,添加FacesValidator批注,并在faces-config.xml中插入Validator声明, 仅此而已 。 一块蛋糕。 但是,让我们考虑以下情形: 您需要自定义日期验证器&#xff0c…

STM32F1笔记(七)WWDG窗口看门狗

窗口看门狗与独立看门狗最大的不同是中断,窗口看门狗拥有一个提前唤醒中断。也就是在快要产生复位的前一段时间(T[6:0]0x40)来提醒需要进行喂狗,否则将复位。因此当窗口看门狗的计数器值减到0x40的时候,产生中断&#…

groovy怎样从sql语句中截取表名_Mysql和SQL

基本概念1.数据库DataBase简称:DB2.什么数据库?——用于存储和管理数据的仓库。存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。3.数据库的特点&#xff1a…

STM32F1笔记(八)时钟

STM32有五种时钟源 1、HSI。高速内部时钟,RC振荡器,频率为8MHz。 2、HSE。高速外部时钟,可接石英/陶瓷谐振器,或者借外部时钟源,频率范围为4MHz~16MHz。 3、PLL。锁相环倍频输出,其时钟输入源可选择为HS…

java常用工具类(一)

一、String工具类 package com.mkyong.common; import java.util.ArrayList; import java.util.List; /** * * String工具类. <br> * * author 宋立君 * date 2014年06月24日 */ public class StringUtil { private static final int INDEX_NO…

python可以下载百度文库_不用下载券也能下载百度文库资料,Python帮你轻松搞定...

大家可能平时都有在百度文库下载文档的经历&#xff0c;费尽心思好不容易在文库找了一份可以用的资料&#xff0c;一看需要用下载券下载&#xff0c;搞的人很烦。 有的人为了节省时间&#xff0c;就任性办理了个文库VIP&#xff0c;再也不用纠结怎么下文档了。如果你是一个百度…

STM32F1笔记(九)通用定时器

STM32F1的定时器分为TIME1/8等高级定时器&#xff0c;TIME2~5等通用定时器&#xff0c;TIME6/7基本定时器。三者的区别主要参考《STM32中文参考手册》里特性的每种定时器主要特性的异同。 先看中文手册中通用定时器的简介&#xff1a; 通用定时器的寄存器有一个比较有趣的地方…

c++保存图标到dll_自动保存邮件附件至指定文件夹

最近有个需求&#xff0c;ERP系统会自动发很多csv附件到我邮箱&#xff0c;我需要把这些附件上传到FTP服务器&#xff0c;服务器会把这些csv的数据写到另外一个系统的数据库。每次大概有30个邮件&#xff0c;每个邮件有一个附件&#xff0c;而且附件的名字都一样&#xff0c;是…

有时在Java中,一个布局管理器是不够的

在开发Java Swing应用程序时&#xff0c;最经常的是&#xff0c;我们需要在多个嵌套面板中使用多个布局管理器。 通常这不是问题&#xff0c;并且被认为是几乎所有人类已知语言的所有UI开发的常规做法。 但是&#xff0c;大多数情况下&#xff0c;对于UI中的每个面板&#xff0…

python中print的用法_Python中print函数简单使用总结

Python中print函数简单使用总结 print函数是Python的入门&#xff0c;每一个学习python的人都绕不开这个函数&#xff0c;下面介绍一下这个函数的用法。 打开电脑&#xff0c;选择python软件&#xff0c;下面选择python 3.7为例进行介绍&#xff0c;点击python 3.7&#xff0c;…

STM32F1笔记(十)PWM

PWM&#xff1a;Pulse Width Modulation&#xff0c;脉冲宽度调制。是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单来说就是对脉冲宽度的控制。 在《STM32中文参考手册》里可以看到 占空比&#xff1a;占空比是指在一个脉冲循环内&#xff0c;通电时…

从GlassFish 3.x扩展到WebLogic 12c Server

Oracle针对GlassFish服务器的策略的主要目标之一是“与Fusion Middleware and Products集成”&#xff08;来源&#xff1a; Community Roadmap&#xff0c;2010年5月 &#xff09;。 在今年早些时候&#xff0c;您听到了很多关于两台服务器合而为一的恐惧和谣言。 看到这两种产…

hashset去重原理_基于simhash的文本去重原理

互联网网页存在着大量重复内容&#xff0c;必须有一套高效的去重算法&#xff0c;否则爬虫将做非常多的无用功&#xff0c;工作时效性无法得到保证&#xff0c;更重要的是用户体验也不好。业界关于文本指纹去重的算法众多&#xff0c;如 k-shingle 算法、google 提出的simhash …

解决express video 手机无法播放的问题

http://stackoverflow.com/questions/24976123/streaming-a-video-file-to-an-html5-video-player-with-node-js-so-that-the-video-c 项目地址 https://github.com/shenggen1987/mp4-demo express index.jade extends layoutblock contenth1 titlep Welcome to #{title}vid…

STM32F1笔记(十一)ADC

查看《STM32中文参考手册》里ADC的介绍和特性 STM32的ADC最大转换速率为1Mhz&#xff0c;即1us&#xff0c;在ADCCLK14M&#xff0c;采样周期为1.5个ADC时钟下得到。当ADC的时钟超过14M时&#xff0c;将导致结果准确度下降。 规则通道相当于正常运行的程序。注入通道就相当于中…

java epoll select_字节跳动高频面试题,操作系统/算法/Java等。

字节跳动# Java▲ 20 Java 中垃圾回收机制中如何判断对象需要回收&#xff1f;常见的 GC 回收算法有哪些&#xff1f;▲ 18 synchronized 关键字底层是如何实现的&#xff1f;它与 Lock 相比优缺点分别是什么&#xff1f;▲ 17 hashmap 和 hashtable 的区别是什么&#xff1f;▲…

STM32F1笔记(十二)DAC

先看《STM32中文参考手册》中DAC的介绍 引脚的定义与ADC类似 这里需要留意手册提供的注意&#xff0c;DAC应该是输出&#xff0c;但是GPIO初始化配置时却要设置为模拟输入。 DAC配置示例 void DAC_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;DAC_InitTypeDef DAC_Init…