因为TCP协议是面向字节流的,上一次和下一次的数据没有明显的数据边界,即TCP通过recv函数接收数据的时候不会区分此条数据是第一次发送的还是第二次发送的,而是直接按规定的大小进行读取,因此有可能读取到不完整的数据或粘在一起的数据。
粘包问题图解如下:
如上图所示机器A向机器B发送的是1+1和2+2,但机器B在接收数据的时候无法区分第一条和第二条数据,所以将第一条和第二条数据粘在一起接收,即接收到1+12+2,这种情况就是数据粘包问题
①使用定长的字节发送(不推荐):它的本质是设置固定的数据收发的字节大小,现实中我们发送数据有长有短,根据每条数据发送的长短给每条数据设置不同的收发长度显然不现实,所以此方法只适用于理论基础实现。
②在应用层当中,对应用程序产生的数据进行“包装”,即给应用数据加上头部描述信息,在应用数据的尾部加上分隔符
eg:应用数据 = “aaabbbccc”
应用数据 = 应用层描述符数据的头部+“aaabbbccc”+分隔符
- HTTP:超文本传输协议
- HTTP协议是无连接,无状态,工作在应用层的协议
①无连接:HTTP协议本身是没有维护连接信息的,HTTP的数据会交给网络协议栈传输层的TCP协议
②无状态:HTTP协议自身不对请求和响应之间的通信状态进行保存;也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理
【问题一】HTTP是无连接的,不会维护连接信息,那么它是否是可靠传输呢?
HTTP是可靠传输的,虽然HTTP无连接,自身不会维护连接信息,但是,它的数据最终会交给传输层的TCP协议,而TCP协议是可靠传输的,因此HTTP协议是可靠传输的
平时我们说的“网址”,其实就是说的URL
以下图为例对URL的各部分进行说明
- http:明文传输,默认端口是80端口
- https:加密传输(一般用非对称加密方式),默认端口是443端口
注意:
像 / ? : 等这样的字符,已经被URL当作特殊意义理解了,因此这些字符不能随意出现,比如,某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义
转义规则如下:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式
- urlencode:将字符转换成为16进制
- urlecode:将16进制数据转换成字符
如上图所示,当我们搜索C++时,’+'被转义为2B,而‘%’的意思是告诉服务器‘%’后面的数据是被 urlencode转换过的
HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。即,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
请求格式图解如下:
验证:
假如我们在百度搜索Linux,然后按F12打开开发者工具,此时我们会看到如下界面
此时打开的开发者工具框什么都没有,是因为我们刚才搜索的内容已经加载过了,才打开的开发者工具,我们只需要刷新页面即可看到如下图所示界面:
然后随便点开一个请求资源名,如下图所示:
① HTTP/0.9(不常用)
HTTP/0.9 HTTP 于 1990 年问世。那时的 HTTP 并没有作为正式的标准被建立。 现在的 HTTP 其实含有 HTTP1.0 之前版本的意思,因此被称为 HTTP/0.9。
② HTTP/1.0 (常用)
HTTP/1.0 HTTP 正式作为标准被公布是在 1996 年的 5 月,版本被命名为 HTTP/1.0,并记载于 RFC1945。虽说是初期标准,但该协议标准至今仍被广泛使用在服务器端。
③ HTTP/1.1(常用)
HTTP/1.1 1997 年 1 月公布的 HTTP/1.1 是目前主流的 HTTP 协议版本。当初的 标准是 RFC2068,之后发布的修订版 RFC2616 就是当前的最新版 本。
④ HTTP/2.0(不常用)
HTTP/2.0 新 一代 HTTP/2.0 正在制订中,但要达到较高的使用覆盖率,仍需假以时日
GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;(GET既能从服务器中去获取数据,也能向服务器中提交少量数据,提交的数据在URL中)
虽然用 GET 方法也可以传输实体的主体,但一般不用 GET 方法进行传输,而是用 POST 方法。虽说 POST 的功能与 GET 很相似,但 POST 的主要目的并不是获取响应的主体内容。(给服务器提交某些数据,提交的数据在正文中)
eg:假设我们要在某个网页进行登录,使用POST请求就会将我们的账号,密码放在请求正文中进行提交
如下图所示我们可以看到POST请求,且在请求正文中可以看到刚才输入的账号密码和验证码
PUT方法用来传输文件,就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URL指定的位置,但是,鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性的问题,因此一般web网站均不使用该方法。也就是说目前PUT方法是不常用的。
HEAD方法和GET方法一样,只是不返回报文主体部分,用来确认资源的有效性,即,HEAD方法是不需要服务端返回响应正文的,使用HEAD方法,服务器只会返回响应首行、响应报头、空行。
DELETE方法用来删除文件,是与PUT相反的方法。HTTP/1.1中的DELETE方法和PUT方法一样,均是不带验证机制的,所以一般的web网站也不使用DELETE方法。
OPTIONS方法用来查询针对请求URL指定的资源支持的方法。即客户端询问当前服务器都支持哪些方法。
浏览器发起了一个HTTP请求,web服务器要告诉浏览器一个状态码(刚刚发起的请求是处理成功了还是失败了)
2XX的响应结果表明请求被正常处理了
表示客户端发来的请求在在服务器端被正常处理,并且返回数据
请求处理成功了,但没有资源要返回(没有正文)
客户端进行了范围请求,服务器成功执行这一请求
3XX响应结果表明浏览器需要进行附加操作以完成请求。
告诉浏览器某一资源已被永久放在另一个URL中,以后访问需访问新的URL
客户端要请求的资源临时被放到某一新i服务器中,以后访问此资源还有访问这个旧服务器
要访问的资源已经更新
4XX的响应结果表明客户端发生错误
服务端无法理解客户端发送的请求
eg:请求格式错误
认证失败
客户端请求访问某一资源被服务器拒绝了,即没有资格(权限)访问某一资源
服务器无法找到客户端请求的资源
5XX的响应结果表明服务器处理请求出错
该状态码表明服务器端在执行请求时发生错误,也有可能是Web应用存在的bug或某些临时的故障
Web服务器在忙
Cookie的作用:
假设有两个人分别在网上商城浏览东西,一个人浏览篮球,一个人浏览衣服,当他们搜索完成后,服务器是怎么知道要把搜索的篮球信息和衣服信息返回给谁,而Cookie就是解决这个问题的,原理如下图所示: