请先自学网络部分:tcp\ip协议、OSI七层模型以及数据包的封装与解封装的过程
1 http协议简介
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。http协议作用在应用层
在了解HTTP如何工作之前,我们先了解计算机之间的通信。HTTP基于tcp/ip。
2 计算机相互之间的通信
互联网的关键技术就是TCP/IP协议。两台计算机之间的通信是通过TCP/IP协议在因特网上进行的。实际上这个是两个协议:
TCP : Transmission Control Protocol 传输控制协议和IP: Internet Protocol 网际协议。
IP:计算机之间的通信
IP协议是计算机用来相互识别的通信的一种机制,每台计算机都有一个IP.用来在internet上标识这台计算机。 IP 负责在因特网上发送和接收数据包。通过 IP,消息(或者其他数据)被分割为小的独立的包,并通过因特网在计算机之间传送。IP 负责将每个包路由至它的目的地。
IP协议仅仅是允许计算机相互发消息,但它并不检查消息是否以发送的次序到达而且没有损坏(只检查关键的头数据)。为了提供消息检验功能,直接在IP协议上设计了传输控制协议TCP.
TCP : 应用程序之间的通信
TCP确保数据包以正确的次序到达,并且尝试确认数据包的内容没有改变。TCP在IP地址之上引端口(port),它允许计算机通过网络提供各种服务。一些端口号为不同的服务保留,而且这些端口号是众所周知。
服务或者守护进程:在提供服务的机器上,有程序监听特定端口上的通信流。例如大多数电子邮件通信流出现在端口25上,用于wwww的HTTP通信流出现在80端口上。
当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信,占用两个计算机之间整个的通信线路。TCP 用于从应用程序到网络的数据传输控制。TCP 负责在数据传送之前将它们分割为 IP 包,然后在它们到达的时候将它们重组。
TCP/IP 就是TCP 和 IP 两个协议在一起协同工作,有上下层次的关系。
TCP 负责应用软件(比如你的浏览器)和网络软件之间的通信。IP 负责计算机之间的通信。TCP 负责将数据分割并装入 IP 包,IP 负责将包发送至接受者,传输过程要经IP路由器负责根据通信量、网络中的错误或者其他参数来进行正确地寻址,然后在它们到达的时候重新组合它们。
3 http工作原理
HTTP协议工作于客户端-服务端架构上的协议。就是浏览器和服务器之间进行“沟通”的一种规范。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
- 以下图表展示了HTTP协议通信流程:
HTTP三点注意事项:特点
- HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
- HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
其他特点:
基于tcp/ip
基于请求/响应模式
3.1 原理:
客户机与服务器建立连接后,发送一个请求给服务器,请求格式为:统一资源标识符、协议版本号。服务器收到请求的信息(包括请求行,请求头,请求体)。服务器接收到请求后,给予相应的响应信息,格式为一个状态行(包括响应行,响应头,响应体)。 |
3.2 工作过程(数据包的封装与解封装)
3.2.1 地址解析
如用客户端浏览器请求这个页面:http://localhost.com:8080/index.htm
从中分解出协议名、主机名、端口、对象路径等部分,对于我们的这个地址,解析得到的结果如下:
协议名:http
主机名:localhost.com
端口:8080
对象路径:/index.html
在这一步,需要域名系统DNS解析域名localhost.com,得主机的IP地址。
3.2.2 封装HTTP请求数据包
把以上部分结合本机自己的信息,封装成一个HTTP请求数据包
3.2.3 封装成TCP包,建立TCP连接(TCP的三次握手)
在HTTP工作开始之前,客户机(Web浏览器)首先要通过网络与服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能,才能进行更高层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。这里是8080端口
3.2.4 客户机发送请求命令
建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可内容。
3.2.5 服务器响应
服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
实体消息是服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
3.2.6 服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码
Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
服务器将响应信息传给客户端,响应体中的内容可能是一个html页面,也可能是一张图片,通过输入流将其读出,并写回到显示器上。其中数据文件中的传输无非就是网络中的封装与解封装的过程,而响应消息接收完成后由浏览器识别文件中的标签,然后显示格式,在然后由BOM的window对象之下的DOM识别动态操作事件渲染到网页上
3.3 请求消息-字符串
请求消息格式
一个完整的http请求消息,包含一个请求行,若干个消息头(请求头),换行,实体内容
3.3.1 请求首行:
描述客户端的请求方式、请求资源的名称、http协议的版本号。 例如: GET/BOOK/JAVA.HTML HTTP/1.1
3.3.1.1 请求方式:get和post的区别
get提交和post提交的区别: GET方式: http默认请求方式----get 将表单数据,以"name=value"形式追加到客户端发送请求的地址栏url路径后面,两者间用"?"隔开,每一个表单的"name=value"间用"&"号隔开。 特点:只适合提交少量信息(浏览器对url的长度有限定),并且不太安全(不要提交敏感数据)、提交的数据类型只限于ASCII字符。 POST方式: 将表单数据直接发送(隐藏)到请求消息的请求体中。POST发送的数据不可见。 特点:可以提交海量信息,相对来说安全一些,提交的数据格式是多样的(Word、Excel、rar、img)。
|
get:
GET /562f25980001b1b106000338.jpg HTTP/1.1 Host img.mukewang.com User-Agent Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 Accept image/webp,image/*,*/*;q=0.8 Referer http://www.imooc.com/ Accept-Encoding gzip, deflate, sdch Accept-Language zh-CN,zh;q=0.8
post:
POST / HTTP1.1 Host:www.wrox.com User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022) Content-Type:application/x-www-form-urlencoded Content-Length:40 Connection: Keep-Alive name=Professional%20Ajax&publisher=Wiley
第一部分:请求行,第一行明了是post请求,以及http1.1版本。
第二部分:请求头部,第二行至第六行。
第三部分:空行,第七行的空行。
第四部分:请求数据,第八行
3.3.1.2 请求资源定位符url
url 的格式:
协议://域名或IP+端口+/路径?参数
(参数就是get请求时的搜索请求的具体内容如 a=1&b=2)
3.3.2 请求头:
1、Host 请求的web服务器域名地址 2、User-Agent HTTP客户端运行的浏览器类型的详细信息。通过该头部信息,web服务器可以判断出http请求的客户端的浏览器的类型。 3、Accept 指定客户端能够接收的内容类型,内容类型的先后次序表示客户都接收的先后次序 4、Accept-Lanuage 指定HTTP客户端浏览器用来展示返回信息优先选择的语言 5、Accept-Encoding 指定客户端浏览器可以支持的web服务器返回内容压缩编码类型。表示允许服务器在将输出内容发送到客户端以前进行压缩,以节约带宽。 而这里设置的就是客户端浏览器所能够支持的返回压缩格式。 6、Accept-Charset HTTP客户端浏览器可以接受的字符编码集 7、Content-Type 显示此HTTP请求提交的内容类型。一般只有post提交时才需要设置该属性 有关Content-Type属性值有如下两种编码类型: (1)“application/x-www-form-urlencoded”: 表单数据向服务器提交时所采用的编码类型,默认的缺省值就是“application/x-www-form-urlencoded”。 然而,在向服务器发送大量的文本、包含非ASCII字符的文本或二进制数据时这种编码方式效率很低。 (2)“multipart/form-data”: 在文件上载时,所使用的编码类型应当是“multipart/form-data”,它既可以发送文本数据,也支持二进制数据上载。 当提交为表单数据时,可以使用“application/x-www-form-urlencoded”;当提交的是文件时,就需要使用“multipart/form-data”编码类型。 8、Keep-Alive 表示是否需要持久连接。如果web服务器端看到这里的值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点
3.3.3 请求体:
请求头和请求体间隔加一行换行符,此换行表示下面是请求体消息
请求体内容:就是指浏览器端通过http协议发送给服务器的实体数据。例如:name=dylan&id=110
3.4 响应消息
可参考:菜鸟教程:点此处
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
例子:
HTTP/1.1 200 OK Date: Fri, 22 May 2009 06:07:21 GMT Content-Type: text/html; charset=UTF-8 <html> <head></head> <body> <!--body goes here--> </body> </html>
第一部分:状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。
第一行为状态行,(HTTP/1.1)表明HTTP版本为1.1版本,状态码为200,状态消息为(ok)
第二部分:消息报头,用来说明客户端要使用的一些附加信息
第二行和第三行为消息报头,
Date:生成响应的日期和时间;Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8
第三部分:空行,消息报头后面的空行是必须的
第四部分:响应正文,服务器返回给客户端的文本信息。
空行后面的html部分为响应正文。
3.4.1 响应首行
协议版本+状态码+状态码的原因短语
响应状态码:
3.4.2 响应头
Server:服务器通过这个头,告诉浏览器服务器的类型
Content-Encoding:告诉浏览器,服务器的数据压缩格式
Content-Length:告诉浏览器,回送数据的长度
Content-Type:告诉浏览器,回送数据的类型
Last-Modified:告诉浏览器当前资源缓存时间
Refresh:告诉浏览器,隔多长时间刷新
Content-Disposition:告诉浏览器以下载的方式打开数据。例如:
context.Response.AddHeader("Content-Disposition","attachment:filename=aa.jpg");
context.Response.WriteFile("aa.jpg");
Transfer-Encoding:告诉浏览器,传送数据的编码格式
ETag:缓存相关的头(可以做到实时更新)
Expries:告诉浏览器回送的资源缓存多长时间。如果是-1或者0,表示不缓存
Cache-Control:控制浏览器不要缓存数据 no-cache
Pragma:控制浏览器不要缓存数据
no-cache
Connection:响应完成后,是否断开连接。 close/Keep-Alive
Date:告诉浏览器,服务器响应时间
3.4.3 响应体
响应头和响应体之间有空行,空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
4 演示案例-web应用的交互
服务端
socket服务器
1 import socket 2 3 def handle_request(client): 4 # 服务端接收到的数据 5 request_data = client.recv(1024) 6 print("request_data: ",request_data) 7 8 with open('login.html','rb') as f: 9 data = f.read() 10 # 给客户端发送的响应消息 11 client.send(b"HTTP/1.1 200 OK\r\nstatus: 200\r\nContent-Type:text/html\r\n\r\n"+data) 12 13 14 def main(): 15 # 创建服务端socket对象 16 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 17 # 绑定服务端IP和端口到套接字 18 sock.bind(('127.0.0.1',8000)) 19 # 服务端等待连接的数量限制 20 sock.listen(5) 21 22 while True: 23 print("the server is waiting for client-connection....") 24 # 服务端accept接收的Conn(全双工管道) 是客户端传过来的socket对象 25 connection, address = sock.accept() 26 # 接收到客户端后的业务处理 27 handle_request(connection) 28 29 # 与客户端断开连接 30 connection.close() 31 32 if __name__ == '__main__': 33 34 main()
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://127.0.0.1:8000/" method="post"> 用户名:<input type="text" name="user"> 密码:<input type="password" name="pwd"> <input type="submit"> </form> </body> </html>
客户端
本文章主要参考有:
以及其他内容