1.http认识

  • HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是互联网上应用最为广泛的一种网络协议,用于web服务器与浏览器之间传输超文本数据的协议

  • HTTP是一个基于TCP/IP通信协议来传递数据(HTML网页文件, 图片文件,视频文件, 查询结果等等)

    html:(Hyper Text Mark-up Language)超文本标记语言,用html来编写网页

  • 通俗的讲: HTTP是在网络上传输HTML网页的协议,用于浏览器和服务器的通信。

2. HTTP 协议的 Request/Response(请求/响应)模型

3. HTTP 请求报文格式分析

 

下面就是我们要请求的示例数据:

GET /index.html HTTP/1.1
Host: 192.168.192.221:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: BAIDUID=8FD6ED496A03231D920484C6379517CF:FG=1;

1.GET / HTTP/1.1 叫做请求行. 里面包含3个信息, 以空格隔开
2.请求头. 除了第一行之外, 剩下的所有数据的格式都是类似的.叫请求头。

请求报文格式总结

4. HTTP 响应报文格式分析

HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 14 Mar 2018 09:52:48 GMT
Server: BWS/1.1
  1.第一行 HTTP/1.1 200 OK 叫做响应行, 共分成3部分, 第一部分 HTTP/1.1 表示 HTTP协议的版本, 第二部分是一个数字, 这个数字表示响应状态码, 用户向服务器发出了请求, 如果服务器正常返回响应报文, 那么状态码一般都是200, 第三部分的 "OK" 表示原因短语, 表示对前面状态码的简单描述. 这里需要说的是, 响应的状态码除了 200 之外, 还有其他的状态码。(其他状态码自己百度)
2.第二行下面的所有内容, 我们叫做响应头. 
 

响应数据格式总结

 

 

浏览器访问网站的过程

基本流程如下:

  1. 用户输入网址.
  2. 浏览器请求DNS服务器, 获取域名对应的IP地址.
  3. 请求连接该IP地址服务器.
  4. 发送资源请求. (HTTP协议)
  5. web服务器接收到请求, 并解析请求, 判断用户意图.
  6. 获取用户想要的资源.
  7. 将资源返回给http服务器程序.
  8. http服务器程序将资源数据通过网络发送给浏览器.
  9. 浏览器解析呈现请求的数据.

TCP通信的整个过程,如下图:

1. TCP短连接

模拟一种TCP短连接的情况:

  1. client 向 server 发起连接请求
  2. server 接到请求,双方建立连接
  3. client 向 server 发送消息
  4. server 回应 client
  5. 一次读写完成,此时双方任何一个都可以发起 close 操作

在步骤5中,一般都是 client 先发起 close 操作。当然也不排除有特殊的情况。

从上面的描述看,短连接一般只会在 client/server 间传递一次读写操作!

 

2. TCP长连接

再模拟一种长连接的情况:

  1. client 向 server 发起连接
  2. server 接到请求,双方建立连接
  3. client 向 server 发送消息
  4. server 回应 client
  5. 一次读写完成,连接不关闭
  6. 后续读写操作...
  7. 长时间操作之后client发起关闭请求

 

3. TCP/IP协议(族)

互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,所以,大家把互联网的协议简称TCP/IP协议(族)

常用的网络协议如下图所示:

  1. 网络接口层(物理层、数据链路层):包括传输介质(网线)、计算机中对应的网络接口卡等,其实这一层tcp/ip协议是没有定义的,给其上层"网络层"提供访问接口.
  2. 网络层(互联网层):主要用IP地址来完成对主机的寻址,它还负责数据包在多种网络中的路由
  3. 运输层:主要为两台主机上的应用提供端到端的通信.
  4. 应用层:为用户提供所需的服务,比如http服务,ftp服务,smtp服务等.

1. 模拟浏览器访问服务端

 

import socket


def main():
    # 1.创建tcp客户端socket对象
    http_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 2. 连接服务端
    http_client_socket.connect(('127.0.0.1', 7788))

    # 3. 发送http请求报文格式
    """
     1. 请求行 : GET /index.html HTTP/1.1
     2. 请求头 : HOST:127.0.0.1:7788
     3. 分隔符   ‘\r\n’
     4. 请求体   product_id=1001
    """
    request_line = 'GET /index.html HTTP/1.1\r\n'  # 请求行,必须有
    request_headers = 'HOST: 127.0.0.1:7788\r\n'  # 请求头
    request_headers += 'Accept: text/html\r\n'
    split = "\r\n"  # 请求头与请求体分隔符
    request_body = "product_id=1001\r\n"
    request_data = request_line + request_headers + split + request_body  # 拼接请求报文数据

    # 发送请求数据到服务端,发送前需编码
    http_client_socket.send(request_data.encode("utf-8"))

    # 等待接受从服务端应答的消息
    response_data = http_client_socket.recv(1024)
    print("http服务端应答的数据:", response_data.decode())  # 解码输出

    # 关闭套接字
    http_client_socket.close()


if __name__ == '__main__':
    main()

  

2. 简单HTTP服务器实现

 1 import socket
 2 
 3 
 4 def handle_client(client_socket):
 5     """处理浏览器客户端的请求"""
 6 
 7     # 等待接收客户端发送的消息
 8     recv_data = client_socket.recv(4096)
 9 
10     # 解码数据
11     request_data = recv_data.decode("utf-8")
12 
13     # 显示接收到的请求报文数据
14     print(request_data)
15 
16     # 按照http 响应报文格式去回复客户端
17     """http 响应报文格式
18      1. 响应行 : HTTP/1.1 200 OK
19      2. 响应头 Server: mimiweb1.0    Connection: Keep-alive
20      3. 分隔符 \r\n
21      4. 响应体  very good
22     """
23     response_line = "HTTP/1.1 200 OK\r\n"  # 响应行,必须有
24     response_headers = "Server: mimiweb1.0\r\n"
25     response_headers += "Connection: Keep-alive\r\n"
26     split = "\r\n"  # 请求头与请求体的分隔符
27     response_body = "very good\r\n"
28 
29     # 拼接响应报文数据
30     response_datas = response_line + response_headers + split + response_body
31 
32     # 向客户端发送响应报文数据
33     client_socket.send(response_datas.encode("utf-8"))
34 
35     # 关闭套接字
36     client_socket.close()
37 
38 
39 def main():
40     """程序主控制入口"""
41 
42     # 创建监听套接字
43     http_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
44 
45     # 当套接字四次挥手,可立即复用地址端口
46     http_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
47 
48     # 服务端绑定端口
49     http_server_socket.bind(('', 7788))
50 
51     # 开启监听
52     http_server_socket.listen(128)
53 
54     # 等待接受浏览器客户端的请求
55     while True:
56         client_socket, client_addr = http_server_socket.accept()
57         print("有新的客户端请求,来自>>>", client_addr)
58 
59         # 在函数中为客户端提供服务
60         handle_client(client_socket)
61 
62 
63 if __name__ == '__main__':
64     main()

服务器端

客户端

 

posted on 2018-06-30 22:13  怪卡  阅读(659)  评论(1编辑  收藏  举报