HTTP(S)
介绍
HTTP--Hyper Text Transfer Protocol,超文本传输协议,是一种建立在TCP上的无状态连接,整个基本的工作流程是客户端发送一个HTTP请求,说明客户端想要访问的资源和请求的动作,服务端收到请求之后,服务端开始处理请求,并根据请求做出相应的动作访问服务器资源,最后通过发送HTTP响应把结果返回给客户端。其中一个请求的开始到一个响应的结束称为事务,当一个事物结束后还会在服务端添加一条日志条目。
HTTP请求
HTTP请求是客户端往服务端发送请求动作,告知服务器自己的要求。HTTP请求由状态行、请求头、请求正文三部分组成:
状态行:包括请求方式Method、资源路径URL、协议版本Version;
请求头:包括一些访问的域名、用户代理、Cookie等信息;
请求正文:就是HTTP请求的数据。
请求方式Method一般有GET、POST、PUT、DELETE,含义分别是获取、修改、上传、删除,其中GET方式仅仅为获取服务器资源,方式较为简单,因此在请求方式为GET的HTTP请求数据中,请求正文部分可以省略,直接将想要获取的资源添加到URL中。
下图为POST请求的格式,有状态行、请求头、请求正文三部分:
HTTP响应
响应数据格式
服务器收到了客户端发来的HTTP请求后,根据HTTP请求中的动作要求,服务端做出具体的动作,将结果回应给客户端,称为HTTP响应。HTTP响应由三部分组成:状态行、响应头、响应正文;
状态行:包括协议版本Version、状态码Status Code、回应短语;
响应头:包括搭建服务器的软件,发送响应的时间,回应数据的格式等信息;
响应正文:就是响应的具体数据。
状态码 | 含义 |
---|---|
1xx | 表示HTTP请求已经接受,继续处理请求 |
2xx | 表示HTTP请求已经处理完成 |
3xx | 表示把请求访问的URL重定向到其他目录 |
4xx | 表示客户端出现错误 |
5xx | 表示服务端出现错误 |
常见状态码含义
常见状态码 | 含义 |
---|---|
200 | OK/请求已经正常处理完毕 |
301 | 请求永久重定向 |
302 | 请求临时重定向 |
304 | 请求被重定向到客户端本地缓存 |
400 | 客户端请求存在语法错误 |
401 | 客户端请求没有经过授权 |
403 | 客户端的请求被服务器拒绝,一般为客户端没有访问权限 |
404 | 客户端请求的URL服务端不存在 |
500 | 服务端永久错误 |
503 | 服务端发生临时错误 |
HTTP响应模型
服务器收到HTTP请求之后,会有多种方法响应这个请求,下面是HTTP响应的四种模型:
单进程I/O模型
服务端开启一个进程,一个进程仅能处理一个请求,并且对请求顺序处理;
多进程I/O模型
服务端并行开启多个进程,同样的一个进程只能处理一个请求,这样服务端就可以同时处理多个请求;
复用I/O模型
服务端开启一个进程,但可以同时开启多个线程,一个线程响应一个请求,同样可以达到同时处理多个请求,线程间并发执行;
复用多线程I/O模型
服务端并行开启多个进程,同时每个进程开启多个线程,这样服务端可以同时处理进程数M*每个进程的线程数N个请求。
HTTP报文格式
HTTP报文是HTTP应用程序之间传输的数据块,HTTP报文分为HTTP请求报文和HTTP响应报文,但是无论哪种报文,他的整体格式是类似的,大致都是由起始、首部、主体三部分组成,起始说明报文的动作,首部说明报文的属性,主体则是报文的数据。接下来具体说明。
HTTP请求报文
请求报文的起始由请求行构成(有些资料称为状态行,名字不一样而已,都是指的一个东西),用来说明该请求想要做什么,由<Method、<URL、<Version 三个字段组成,注意每个字段之间都有一个空格。其中<Method字段有不同的值:
Method | 含义 |
---|---|
GET | 访问服务器的资源 |
POST | 向服务器发送要修改的数据 |
HEAD | 获取服务器文档的首部 |
PUT | 向服务器上传资源 |
DELETE | 删除服务器的资源 |
<URL字段表示服务器的资源目录定位
<Version字段表示使用的HTTP协议版本
首部部分由多个请求头(首部行)构成,部分首部字段名如下:
首部字段名 | 含义 |
---|---|
Accept | 指定客户端能够接收的内容格式类型 |
Accept-Language | 指定客户端能够接受的语言类型 |
Accept-Ecoding | 指定客户端能够接受的编码类型 |
User-Agent | 用户代理,向服务器说明自己的操作系统、浏览器等信息 |
Connection | 是否开启持久连接(keep-alive) |
Host | 服务器域名 |
主体部分就是报文的具体数据。
HTTP响应报文
响应报文的起始由状态行构成,用来说明服务器做了什么,由<Version、<Status-Code、<Phrase三个字段组成,同样的每个字段之间留有空格;首部由多个响应头(也叫首部行)组成,部分首部字段名如下:
首部字段名 | 含义 |
---|---|
Server | 服务器软件名,Apache/Nginx |
Date | 服务器发出响应报文的时间 |
Last-Modified | 请求资源的最后的修改时间 |
主体部分是响应报文的具体数据。
HTTP协议版本更替
HTTP/0.9
HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源。
HTTP/1.0
在0.9版本上做了进步,增加了请求方式POST和HEAD;不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等;同时也开始支持cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可。
但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keep-alive。
HTTP/1.1
解决了1.0版本的keep-alive问题,1.1版本加入了持久连接,一个TCP连接可以允许多个HTTP请求; 加入了管道机制,一个TCP连接同时允许多个请求同时发送,增加了并发性;新增了请求方式PUT、PATCH、DELETE等.
但是还存在一些问题,服务端是按队列顺序处理请求的,假如一个请求处理时间很长,则会导致后边的请求无法处理,这样就造成了队头阻塞的问题;同时HTTP是无状态的连接,因此每次请求都需要添加重复的字段,降低了带宽的利用率。
HTTP/2.0
为了解决1.1版本利用率不高的问题,提出了HTTP/2.0版本。增加双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题;HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。另外也增加服务器推送的功能,即不经请求服务端主动向客户端发送数据。
当前主流的协议版本还是HTTP/1.1版本。
网络访问量
IP:IP访问量
相同的公网IP计算一次,就是同一个局域网内的所有用户访问一个网站,但是他们都是借助一个公网IP去访问那个网站的(NAT),因此这也只能算作一个IP访问量。换一次公网IP则会加1。
PV:网页访问量
用户访问的页面数就是PV访问量,同一个局域网的不同用户,而且就算是同一个用户,只要刷新一次网站页面,PV访问量就加1,三个访问量的值往往数PV的值最大。
UV:访客访问量
这里的访客不是用户,而是电脑,一台电脑算一个访客,即使是同一台电脑的不同用户,访问同一个网站UV也只能加1,只有更换电脑才会使UV加1,因为服务端会记录客户端电脑的信息。
HTTPS
介绍
HTTPS是以安全为目标的HTTP通道,是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
HTTP与HTTPS的区别
1.HTTPS协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2.HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSL加密传输协议。
3.HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4.HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
HTTPS的工作原理
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤:
1.客户使用HTTPS的URL访问Web服务器,要求与Web服务器建立SSL连接。
2.Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
3.客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。
4.客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
5.Web服务器利用自己的私钥解密出会话密钥。
6.Web服务器利用会话密钥加密与客户端之间的通信。
HTTPS的优缺点
优点
1.使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
2.HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
3.HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
4.谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名将会更高”。
缺点
1.HTTPS协议握手阶段比较费时,会使页面的加载时间延长近50%,增加10%到20%的耗电;
2.HTTPS连接缓存不如HTTP高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;
3.SSL证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
4.SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗。
5.HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行。
Socket
介绍
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
图解
通信步骤
例子
client
public class Client {
public static void main(String[] args) throws Exception {
ServerSocket server_socket = new ServerSocket(8080);
Socket socket = server_socket.accept();
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String str;
while ((str = reader.readLine()) != null) {
System.out.println("我是服务端,我收到的消息是:" + str);
}
//用完关闭
reader.close();
inputStream.close();
socket.close();
server_socket.close();
}
}
server
public class Server {
public static void main(String[] args) throws Exception{
Socket server_socket = new Socket("127.0.0.1",8080);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(server_socket.getOutputStream()));
writer.write("你好,jimyoungwei ,这里是客户端给你发的消息。");
writer.flush();
writer.close();
server_socket.close();
}
}
先运行client,再运行server,运行结果:
/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=62225:/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Users/jimyoungwei/IdeaProjects/SocketTest/out/production/SocketTest com.jimyoungwei.Client
我是服务端,我收到的消息是:你好,jimyoungwei ,这里是客户端给你发的消息。
Process finished with exit code 0
TCP/UDP
基本认知
TCP和UDP是OSI模型中的运输层中的协议。TCP提供可靠的通信传输,而UDP则常被用于让广播和细节控制交给应用的通信传输。
TCP(Transmission Control Protocol,传输控制协议):
连接三次握手:
第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
断开四次分手:
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
名词解析:
ACK :TCP报头的控制位之一,对数据进行确认.确认由目的端发出,用它来告诉发送端这个序列号之前的数据段都收到了.比如,确认号为X,则表示前X-1个数据段都收到了,只有当ACK=1时,确认号才有效,当ACK=0时,确认号无效,这时会要求重传数据,保证数据的完整性。
SYN : 同步序列号,TCP建立连接时将这个位置设置为1。
FIN :发送端完成发送任务后,当TCP完成数据传输需要断开时,提出断开连接的一方将其设置为1。
包头结构:
源端口 16位
目标端口 16位
序列号 32位
回应序号 32位
TCP头长度 4位
reserved 6位
控制代码 6位
窗口大小 16位
偏移量 16位
校验和 16位
选项 32位(可选)
这样我们得出了TCP包头的最小长度,为20字节
UDP(User Data Protocol,用户数据报协议):
特点:
1.UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
2.由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
3.UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
4.吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
5.UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。
6.UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。
使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。
包头结构:
源端口 16位
目的端口 16位
长度 16位
校验和 16位
优点
TCP:
可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。
UDP:
快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击。
缺点
TCP:
慢,效率低,占用系统资源高,易被攻击 。TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
UDP:
不可靠,不稳定。 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。
应用场景
TCP:
当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下: 浏览器用的HTTP FlashFXP,用的FTP Outlook、用的POP、SMTP Putty,用的Telnet、SSH QQ文件传输 ……
UDP:
面向数据报方式,网络数据大多为短消息,拥有大量Client,对数据安全性无特殊要求,网络负担非常重,但对响应速度要求高,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 、QQ视频 、TFTP ……
网络编程
具体编程时区别:
1.socket()的参数不同。
2.UDP Server不需要调用listen和accept 。
3.UDP收发数据用sendto/recvfrom函数 。
4.TCP:地址信息在connect/accept时确定 。
5.UDP:在sendto/recvfrom函数中每次均 需指定地址信息 。
6.UDP:shutdown函数无效。
服务器端编程一般步骤:
TCP:
1、创建一个socket,用函数socket()。
2、设置socket属性,用函数setsockopt(); * 可选 。
3、绑定IP地址、端口等信息到socket上,用函数bind()。
4、开启监听,用函数listen()。
5、接收客户端上来的连接,用函数accept()。
6、收发数据,用函数send()和recv(),或者read()和write()。
7、关闭网络连接。
8、关闭监听。
UDP:
1、创建一个socket,用函数socket()。
2、设置socket属性,用函数setsockopt();* 可选 。
3、绑定IP地址、端口等信息到socket上,用函数bind()。
4、循环接收数据,用函数recvfrom()。
5、关闭网络连接。
客户端编程一般步骤:
TCP:
1、创建一个socket,用函数socket()。
2、设置socket属性,用函数setsockopt();* 可选 。
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 。
4、设置要连接的对方的IP地址和端口等属性。
5、连接服务器,用函数connect()。
6、收发数据,用函数send()和recv(),或者read()和write()。
7、关闭网络连接。
UDP:
1、创建一个socket,用函数socket()。
2、设置socket属性,用函数setsockopt();* 可选 。
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 。
4、设置对方的IP地址和端口等属性。
5、发送数据,用函数sendto()。
6、关闭网络连接。
区别
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。
2、TCP提供可靠的服务。通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的。UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)。
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节。
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。
上一篇:Android基础(9)—多线程和异步任务
下一篇:Android基础(11)—你需要知道的内存知识
精彩内容不够看?更多精彩内容,请到微信搜索 “危君子频道” 订阅号,每周更新,欢迎大家关注订阅!