HTTP
1.1、HTTP的概念
HTTP是一种网络传输协议,位于TCP/IP协议族的最顶层——应用层。Hypertext Transfer Protocol
超文本传输协议,和 HTML (Hypertext Markup Language
超文本标记语言一起诞生,用于在网络上请求和传输HTML内容。
OSI的7层协议:从下到上分别是:7-应用层、6-表示层、5-会话层、4-传输层、3-网络层、2-数据链路层、1-物理层。
TCP三次握手(作用是建立连接)和四次挥手(作用是断开连接)——保证数据传输可靠性。
HTTP协议是一个超文本传输协议。HTTP协议是一个基于TCP传输协议传输数据的。HTTP协议规定了浏览器和Web服务器通信数据的格式。
1.2、URL
URL的英文全拼是(Uniform Resoure Locator),表达的意思是统一资源定位符,通俗理解就是网络资源地址,也就是我们常说的网址。
URL三部分组成:协议类型、服务器地址(和端口号)、资源路径(Path),查询参数部分(可选)。
协议类型://服务器地址[:端口号]路径
1.3、报文
通信是以报文的形式。
请求报文
请求行: method、path、Http version
Headers:Host、Content-Type、Content-Length
Body
响应报文
状态行: Http version、status code、status message
Headers:Content-Type、cache-control、vary、etag、content-encoding
Body
请求头和响应头详细参考网站
http://tools.jb51.net/table/http_header
一个HTTP请求报文可以由请求行、请求头、空行和请求体4个部分组成。
请求行是由三部分组成:请求方式、请求资源路径、HTTP协议版本。
GET方式的请求报文没有请求体,只有请求行、请求头、空行组成。
POST方式的请求报文可以有请求行、请求头、空行、请求体四部分组成,注意:POST方式可以允许没有请求体,但是这种格式很少见。
一个HTTP响应报文是由响应行、响应头、空行和响应体4个部分组成。
响应行是由三部分组成:HTTP协议版本、状态码、状态描述。
1.4、请求方法
GET:对服务器数据不进行修改、不发送Body。幂等(反复调用多次会得到相同的结果)。
@GET("/users/{id}")
Call<User> getUser(@Path("id") String id, @Query("gender") String gender);
POST:用于增加或修改资源、不幂等。
@FormUrlEncoded
@POST("/users")
Call<User> addUser(@Field("name") String name, @Field("gender") String gender);
PUT:仅用于修改资源、发送给服务器的内容写在Body里面、幂等。
@FormUrlEncoded
@PUT("/users/{id}")
Call<User> updateGender(@Path("id") String id, @Field("gender") String gender);
DELETE:用于删除资源、不发送Body、幂等。
@DELETE("/users/{id}")
Call<User> getUser(@Path("id") String id, @Query("gender") String gender);
HEAD:和GET使用方法完全相同,唯一区别在于,返回的响应中没有Body。
1.5、HTTP状态码
1xx: Infomational (信息状态码) ,临时性消息,如:100 (继续发送)、101(正在切换协议)
2xx: Succeed(成功),请求正常处理完毕,如 200
3xx: Redirection(重定向),需要进行附加操作,一般是没有响应数据返回的,如 304(Not,modified)307
4xx: Client Error (客户端的错误),服务器无法处理请求,如 404
5xx: Server Error (服务端的错误),服务器处理请求出错,如 500
1.5、Content-Type
指定Body的类型。主要有四类:
text/html:请求Web页面是返回响应的类型,Body中返回html文本。
x-www-form-urlencoded:Web页面纯文本表单的提交方式。
@FormUrlEncoded
@POST("/users")
Call<User> addUser(@Field("name") String name, @Field("gender") String gender);
multitype/form-data:Web页面含有二进制文件时的提交方式。
Content-Type: multipart/form-data; boundary=----
@Multipart
@POST("/users")
Call<User> addUser(@Part("name") RequestBody name, @Part("avatar") RequestBody avatar);
RequestBody namePart = RequestBody.create(MediaType.parse("text/plain"),nameStr);
RequestBody avatarPart = RequestBody.create(MediaType.parse("image/jpeg"),avatarFile);
api.addUser(namePart, avatarPart);
**application/json,image/jpeg,application/zip…**单项内容(文本或非文本都可以),用于Web Api的响应或者POST/PUT的请求。
@POST("/users")
Call<User> addUser(@Body("user") User user);
@POST("users/{id}/avatar")
Call<User> updateAvatar(@Path("id") String id, @Body RequestBody avatar);
RequestBody avatarBody = RequestBody.create(MediaType.parse("image/jpeg"),avatarFile);
api.updateAvatar(id, avatarBody)
1.6、Header
HTTP消息的元数据 (meta data)
User-Agent:用户代理,即是谁实际发送请求、接受响应的,例如收机浏览器、某款收机App。
Host:服务器主机地址
Content-Length:长度
Location:重定向的目标 URL
Cookie/Set-Cookie:发送Cookie/设置Cookie
Authorization:授权信息
Accept: 客户端能接受的数据类型。如 text/html
Accept-Charset: 客户端接受的字符集。如 utf-8
Accept-Encoding: 客户端接受的压缩编码类型。如 gzip
Content-Encoding:压缩类型。如 gzip
1.7、Range
Accept-Range: bytes 响应报文中出现,表示服务器支持按字节来取范围数据
Range: bytes=<start>-<end>
请求报文中出现,表示要取哪段数据
Content-Range:<start>-<end>/total
响应报⽂中出现,表示发送的是哪段数据
作用:断点续传、多线程下载。
1.8、Cache
Cache 和 Buffer 的区别
Cache-Control: no-cache、no-store、max-age
Last-Modified
If-Modified-Since
Etag
If-None-Match
Cache-Control: private / public
2、加密
2.1、对称加密
DES(56位密钥,密钥太短而逐渐被弃用)、AES(128位、192位、256位密钥,现在最流行)。
2.2、非对称加密
使用公钥对数据进行加密得到密文;使用私钥对数据进行解密得到原数据。
缺点:双方公钥都暴漏,可能会伪造数据。
如果用私钥对数据加密,使用公钥是可以解密得到原数据的。但是一般不要互换,签名和验证就是这样,传输数据包括原数据+签名数据。
签名一般先对原数据hash,再进行签名。
用非对称加密+签名来传输数据 -> 密文 + 签名数据。 解决上面的缺点。
经典算法:RSA(可用于加密和签名)、DSA(仅用于签名,但速度更快)。
2.3、Base64
将二进制数据转换成由64个字符组成的字符串的编码算法。64个字符:a-z
、A-Z
、0-9
、+
、/
。
作用:让原数据具有字符串所具有的特性,如可以放在URL中传输、可以保存到文本文件。
Base64的缺点:因为自身的原理(6位变8位),因此每次Base64编码之后,数据都会增大约1/3,所以会影响存储和传输性能。
Base64并不是加密。
Base58:比特币使用的编码方式,去掉了Base64中的数字0
,字母大写O
,字母大写I
,和字母小写l
,以及 “+” 和 “/“ 符号,用于比特币地址的表示。
URL encoding
:在URL的字符串中,对一些不用于特殊用途的保留字符,使⽤百分号%
为前缀进行单独编码,以避免出现解析错误。
2.4、序列化
把数据对象(一般是内存中的,例如 JVM 中的对象)转换成字节序列的过程。对象在程序内存里的存放形式是散乱的(存放在不同的内存区域、并且由引用进行连接),通过序列化可以把内存中的对象转换成一个字节序列,从而使用byte[]
等形式进行本地存储或网络传输,在需要的时候重新组装(反序列化)来使用。
目的:让内存中的对象可以被储存和传输。
序列化是编码吗?不是。编码是把数据由一种数据格式转换成另一种数据格式;而序列化是把数据由内存中的对象(而不是某种具体的格式)转换成字节序列。
2.5、Hash
定义:把任意数据转换成指定大小范围(通常很小,例如256字节以内)的数据。
作用:相当于从数据中提出摘要信息,因此最主要用途是数字指纹。
经典算法:MD5
、SHA1
、SHA256
等。
Hash的实际用途:唯一性验证。
例如 Java 中的 hashCode()
方法。怎么重写hashCode方法?
把 equals() 方法中的每个用于判断相等的变量都放进 hashCode() 中,一起生成一个尽量不会碰撞的整数即可。
为什么每次重写 equals() 方法都需要?因为要把新的判断条件放进hashCode()。
Hash的实际用途:数据完整性验证
从网络上下载文件后,通过比对文件的Hash值(例如 MD5、SHA1),可以确认下载的文件是否有损坏。
Hash 的实际用途:快速查找
HashMap
Hash 的实际用途:隐私保护
当重要数据必须暴露的时候,可以选择暴露它的Hash值(例如 MD5),以保障原数据的安全。
例如网站登录时,可以只保存用户密码的 Hash 值,在每次登录验证时只需要将输入的密码的Hash值和数据库中保存的 Hash 值作比对就好,网站无需知道用户的密码。这样,当网站数据失窃时,用户不会因为密码被盗导致其他网站的安全也受到威胁。
Hash是单向过程,往往是不可逆的,无法进行逆向恢复操作,因此Hash不属于编码。
Hash是单向过程,无法进行逆向回复操作,因此Hash不属于加密。(MD5不是加密!)
3、HTTPS
3.1、TCP/IP协议
具体分层:
Application Layer
应用层:HTTP、FTP、DNS。
Transport Layer
传输层:TCP、UDP。
Internet Layer
网络层:IP。
Link Layer
数据链路层:以太网、Wi-Fi。
三次握手:客户端:「我要向你发送消息」;服务器:「好的。我要向你发送消息」;客户端:「好的」。
四次挥手:客户端:「我不再给你发送消息」;服务端:「好的」;服务端:「我不再给你发送消息」;客户端:「好的」。
为什么四次挥手而不是三次:因为在客户端停止向服务器发送消息时,也许服务器还有消息需要向客户端发送,因此在它对客户端的「Fin」(即「我不再给你发送消息」,这个词不必记住)消息进行回应时,不需要立即附加上「我也不再向你发送消息」。在稍后服务器的消息发送完毕之后,才需要向客户端发送通知。
长连接:因为移动网络并不在Internet
中,而是在运营商的内网,并不具有真正的公网 IP
,因此当某个 TCP
连接在一段时间不通信之后,网关会出于网络性能考虑而关闭这条 TCP
连接和公网的连接通道,导致这个 TCP
端口不再能收到外部通信消息,即 TCP
连接被动关闭。
长连接的实现方式:心跳。即在一定间隔时间内,使用 TCP 连接发送超短无意义消息来让网关不能将自己定义为「空闲连接」,从而防止网关将自己的连接关闭。
3.2、HTTPS
定义:HTTP在SSL(或 TLS)上工作。 简单说就是加密通信的HTTP。
工作原理:在客户端和服务器之间协商出一套对称密钥,每次发送信息之前将内容加密,收到之后解密,达到内容的加密传输。因为对称加密性能更好。
为什么不直接用非对称加密?非对称加密由于使用了复杂了数学原理,因此计算相当复杂,如果完全使用非对称加密来加密通信内容,会严重影响网络通信的性能。
HTTPS 连接建⽴的过程
客户端请求建立连接Client Hello
服务端Server Hello
服务器发送证书(非对称加密的公钥、签名等)- 信任建立
客户端发给服务器Pre-master Secret(非对称加密随机数)
客户端通知:将使用加密通信
客户端发送:Finished
服务器通知:将使用加密通信
服务器发送:Finished
客户端加密密钥(客户端发送消息)、服务端加密密钥(服务端发送消息)、客户端MAC Secret(验证身份)、服务端MAC Secret(验证身份)。
4、网络编程
4.1、IP地址
IP地址的作用是标识网络中唯一的一台设备的。
IP地址的表现形式分为: IPv4和IPv6。IPv4是目前使用的ip地址;IPv6是未来使用的ip地址;IPv4是由点分十进制组成;IPv6是由冒号十六进制组成。
查看IP地址:Linux 和 mac OS 使用 ifconfig
这个命令;Windows 使用 ipconfig
这个命令。
检查网络:ping
ping www.baidu.com 检查是否能上公网
ping 当前局域网的ip地址 检查是否在同一个局域网内
ping 127.0.0.1 检查本地网卡是否正常
4.2、端口和端口号
端口的作用就是给运行的应用程序提供传输数据的通道。好比房间的门,是数据传输必经之路。
每一个端口都会有一个对应的端口号,好比每个房间的门都有一个门牌号,想要找到端口通过端口号即可。
操作系统为了统一管理这么多端口,就对端口进行了编号,这就是端口号,端口号其实就是一个数字,好比我们现实生活中的门牌号,端口号有65536个。
端口号的作用是用来区分和管理不同端口的,通过端口号能找到唯一个的一个端口。
端口和端口号的关系:端口号可以标识唯一的一个端口。
端口号可以分为两类:知名端口号和动态端口号。
知名端口号的范围是0到1023。这些端口号一般固定分配给一些服务,比如21端口分配给FTP(文件传输协议)服务,25端口分配给SMTP(简单邮件传输协议)服务,80端口分配给HTTP服务。
动态端口号的范围是1024到65535。如果程序员开发的程序没有设置端口号,操作系统会在动态端口号这个范围内随机生成一个给开发的应用程序使用。当运行一个程序默认会有一个端口号,当这个程序退出时,所占用的这个端口号就会被释放。
4.3、TCP的介绍
通过 IP 地址能够找到对应的设备,然后再通过端口号找到对应的端口,再通过端口把数据传输给应用程序,这里要注意,数据不能随便发送,在发送之前还需要选择一个对应的传输协议,保证程序之间按照指定的传输规则进行数据的通信, 而这个传输协议就是TCP。
TCP的英文全拼(Transmission Control Protocol)简称传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP通信步骤:创建连接、传输数据、关闭连接。
TCP的特点:
- 面向连接:通信双方必须先建立好连接才能进行数据的传输,数据传输完成后,双方必须断开此连接,以释放系统资源。
- 可靠传输:TCP 采用发送应答机制、超时重传、错误校验、流量控制和阻塞管理。
4.4、socket的介绍
为了保证数据的完整性和可靠性我们使用tcp传输协议进行数据的传输,为了能够找到对应设备我们需要使用ip地址,为了区别某个端口的应用程序接收数据我们需要使用端口号,那么通信数据是如何完成传输的呢?使用socket来完成。
socket是进程之间通信一个工具,好比现实生活中的插座,所有的家用电器要想工作都是基于插座进行,进程之间想要进行网络通信需要基于这个 socket。
socket的作用:负责进程之间的网络数据传输,好比数据的搬运工。
只要跟网络相关的应用程序或者软件都使用到了socket。进程之间网络数据的传输可以通过socket来完成,socke 就是进程间网络数据通信的工具。
4.5、TCP网络应用程序开发流程
TCP网络应用程序开发分为:TCP客户端程序开发和TCP服务端程序开发。
主动发起建立连接请求的是客户端程序,等待接受连接请求的是服务端程序。