再谈协议
协议是一种 "约定". socket api的接口,在读写数据时,都是按 "字符串" 的方式来发送接收的(tcp是以字节流的方式发送的,这里便与表述使用"字符串")
如果我们要传输一些"结构化的数据" 怎么办呢?
那么我们(TCP)在收到一个报文的时候,如何保证你收到了一个完整的报文?
tcp是面向字节流的,所以要明确报文和报文的边界
我们调用的所有的发送函数,根本就不是把数据发送到网络中,发送函数,本质是拷贝函数tcp发送的本质,其实就是将数据从c的发送缓冲区,拷贝到s的接受缓冲区:tcp是全双工的!
HTTP协议
虽然我们说, 应用层协议是我们程序猿自己定的.
但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)
就是其中之一.
认识URL
平时我们俗称的 "网址" 其实就是说的 URL
一切你在网络中看到的都是资源,这些资源文件在你服务器的磁盘上,拿到这些文件就需要Linux系统的路径结构,http就是通过http协议从服务器上拿下来对应的"资源"。因为文件资源种类特别多,http都能搞定,所以:http协议为超文本传输协议。
不要认为在https的网址上没有看见端口号就真的没有端口号,只是一般而言端口号采用默认的443
urlencode和urldecode
像/ ? :
等这样的字符,已经被url
当做特殊意义理解了,因此这些字符不能随意出现。
比如,某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义。
转义的规则如下:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式
"+" 被转义成了 "%2B",urldecode就是urlencode的逆过程;
HTTP协议格式
HTTP请求:
- 首行: [方法] + [url] + [版本]
- Header:请求的属性,冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
- Body:空行后面的内容都是Body。Body允许为空字符串。如果Body存在,则在Header中会有一个Content-Length属性来标识Body的长度;
细节:
1.请求和响应怎么保证应用层完整读取完毕了?
- 我可以读取完整的一行
- while(读取完整的一行) 一 所有的请求行+请求报头全部读完 一 直到空行
- 我们能保证把报头读完,报头有一个属性: Content-Length: XXX正文长度
- 解析出来内容长度,在根据内容长度,读取正文即可
2.请求和响应是怎么做到序列化和反序列化的?
http自己实现的,第一行+请求/响应报头,只要按照\r\n将字符串1->n即可。正文不用做
HTTP响应:
- 首行:[版本号] + [状态码] + [状态码解释]
- Header:请求的属性,冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
- Body:空行后面的内容都是Body。Body允许为空字符串。如果Body存在,则在Header中会有一个
- Content-Length属性来标识Body的长度;如果服务器返回了一个html页面,那么html页面内容就是在body中。
HTTP的方法
其中最常用的就是GET方法和POST方法.
我们进行数据提交的时候,本质前端要通过form表单
提交的,浏览器会自动将form表单中的内容转换成为GET/POST
方法请求
- GET方法:
- POST方法:
区别: - GET通过url传递参数,具体: http://ip:port/Xxx/YY?name=value&name2=value2
- POST提交参数通过http请求的正文提交参数!
- Post方法通过正文提交参数,所以一般用户看不到,私密性更好,私密性!=安全性,GET方法不私密
- 无论是GET和POST方法,都不安全!要谈安全,必须加密!
- 通过URL传递参数,注定了不能太大,但是POST方法,通过正文,正文可以很大,甚至可以是其他的东西
HTTP的状态码
最常见的状态码, 比如 200(OK), 404(Not Found), 403(Forbidden), 302(Redirect, 重定向), 504(Bad Gateway)
什么是重定向?就是server告诉client,由客户端完成
- 临时重定向:比如自动跳转到广告商
- 永久重定向:比如一个公司以前用的域名更换了,但是用户不知道,所以就给旧域名一个重定向到新的域名,来防止用户找不到新地址。
HTTP常见Header
- Content-Type: 数据类型(text/html等)
- Content-Length: Body的长度
- Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
- User-Agent: 声明用户的操作系统和浏览器版本信息;
- referer: 当前页面是从哪个页面跳转过来的;
- location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;
- Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;
长连接:
其实一张我们看到的网页,实际上可能由多种元素构成,所以一张完整的网页需要多次http请求
http网页中可能包含多个元素,http是基于tcp的,如果频繁发起http请求,那么就会有tcp面向链接的频繁创建链接的问题
长连接:建立好一条链接,获取一大份资源的时候,通过同一条链接完成
建立长连接需要client和server都要支持,才能建立,显示Connection: keep-alive
表示支持长连接,显示Connection: close
表示短链接
HTTP周边会话保持
HTTP无状态协议,是指协议对于交互性场景没有记忆能力。
比如点击一个纯的html网页,请求获取服务器的html文件资源时,每次http请求都会返回同样的信息,因为这个是没有交互的,每一次的请求都是相互独立的。在无交互场景中上面那样,当然也不会有太大的问题。但是对于涉及到动态交互的场景,就显得很尴尬了
会话保持严格意义不是http天然具备的,是后面使用发现需要的,http协议是无状态的。但是用户需要。因为用户查看新的网页是常规操作,如果发生网页跳转,那么新的页面也就无法识别是哪一个用户了,为了让用户一经登陆,可以在整个网站,按照自己的身份进行随意访问
cookie技术:
- cookie文件:比如你登陆了一个网站,关闭浏览器,结束掉这个进程,你再次登陆这个浏览器的网站,你不需要重新登陆,这就是文件级别的。
- cookie内存:跟上面例子相反,你没有关闭浏览器,你关闭这个网站重新打开不需要登陆,但是你关闭浏览器以后,再次打开这个浏览器的网站就需要重新登陆。(使用文件还是内存可以自行配置)
配合策略:比如异地登陆提醒等。
比如你个人的信息被黑客盗取走问题可能不是特别严重,但是如果企业的信息被盗取,问题就上升了几个档次。
如有错误或者不清楚的地方欢迎私信或者评论指出🚀🚀