http协议
请求
# 请求行 请求方式 得到的文件 协议版本
GET /index.html HTTP/1.1
# 请求头 告诉服务器 我的特征 我有什么 我能做什么 我需要什么 我能接受什么
Host: 127.0.0.1:8888
# 保持长连接 close 短连接
Connection: keep-alive
Upgrade-Insecure-Requests: 1
# 浏览器信息 非常重要
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 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, br
# 我能接收的语言
Accept-Language: zh-CN,zh;q=0.9
响应
# 响应行
HTTP/1.1 200 OK
# 响应头
Server: codewen
# 告诉浏览器我的文件类型和编码
Content-Type: text/html;charset=UTF-8
# 响应头和响应体之间要空行
# 响应主体
aaaaaaa
长连接:3次握手,浏览器发一送一次请求,服务器响应请求,浏览器发一送一次请求,服务器响应请求,浏览器发一送一次请求,服务器响应请求,如果长时间没有请求,服务端断开连接,4次分手
短连接:3次握手,浏览器发一送一次请求,服务器响应请求,服务端断开连接,4次分手
静态Web服务器
from socket import *
# 声明一个常量 网站根目录 全部大小写
WEB_DIR = "html"
def main():
# 1.创建对象
tcp_server = socket()
# 2不会出现端口被占用
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 2.绑定IP地址和端口
tcp_server.bind(("", 9999))
# 3.改主动为被动
tcp_server.listen(5)
# 4.等待连接
while True:
new_socket, client_info = tcp_server.accept()
# 5.接收消息
raw_data = new_socket.recv(1024)
# 5.1 转码
request_data = raw_data.decode("utf-8")
# 5.2 按行分割
request_data = request_data.splitlines()
# 5.3 得到请求行 GET /2.html HTTP/1.1
request_start_line = request_data[0]
# 5.4 得到文件名 分割
file_name = request_start_line.split(" ")[1]
print(file_name)
# 5.4.1 判断文件名是不是 / 如果是一个/ 那就是首页
if file_name == "/":
file_name = "/index.html"
# 5.5 得到文件完整路径
file_name = WEB_DIR + file_name
# 5.6 打开文件
try:
with open(file_name, 'rb') as fr:
file_data = fr.read()
except:
# 6.响应
response_start = "HTTP/1.1 404 Not found\r\n"
response_header = "Server: codewen\r\n"
response_header += "Content-Type: text/html;charset=UTF-8\r\n"
response_body = "\r\n此网页不存在\r\n"
data = response_start + response_header + response_body
new_socket.send(data.encode('utf-8'))
# 7.关闭
new_socket.close()
else:
# print(f"{file_data}")
# 6.响应
response_start = b"HTTP/1.1 200 OK\r\n"
response_header = b"Server: codewen\r\n\r\n"
response_body = file_data
data = response_start + response_header + response_body
new_socket.send(data)
# 7.关闭
new_socket.close()
if __name__ == '__main__':
main()
面向对象服务器
from socket import *
from multiprocessing import Process
# 声明一个常量 网站根目录
WEB_ROOT = "html"
class WebServer(object):
def __init__(self, port=8000, max_listen=5):
# 1.创建Socket对象
self.tcp_server = socket()
# 设置socket属性为非阻塞
self.tcp_server.setblocking(True)
# 2不会出现端口被占用
self.tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 2.绑定IP地址和端口
self.tcp_server.bind(("", port))
# 3.把主动模式变成被动模式,一旦改变,这个Socket对象只能接,不能拨号
self.tcp_server.listen(max_listen)
print(f"当前服务端口:{port}")
def handle_data(self, new_socket, client_info):
print(f"有新的客户{client_info}来了")
# 5.接收消息
raw_data = new_socket.recv(1024)
# 6.得到请求的信息
request_data = raw_data.decode("utf-8")
# 7. 按回车分割
request_data_lines = request_data.splitlines()
# 8. 得到第一行 请求行 GET /2.html HTTP/1.1
request_data_start = request_data_lines[0]
# 9. 得到文件外 "html" + "/2.html"
file_name = WEB_ROOT + request_data_start.split(" ")[1]
# 10. 得到文件的内容
try:
with open(file_name, "rb") as fr:
file_data = fr.read()
except:
# 11.响应
# 响应行
response_start = b"HTTP/1.1 404 Not Found\r\n"
# 响应头
response_header = b"Server: codewen\r\n"
response_header += b"Content - Type: text / html;charset = UTF - 8\r\n\r\n"
# 主体
response_body = "此网页被吃掉了".encode("utf-8")
response_data = response_start + response_header + response_body
# 发送数据
new_socket.send(response_data)
# 6.关闭连接
new_socket.close()
else:
# 11.响应
# 响应行
response_start = b"HTTP/1.1 200 OK\r\n"
# 响应头
response_header = b"Server: codewen\r\n"
response_header += b"Content - Type: text / html;charset = UTF - 8\r\n\r\n"
# 主体
response_body = file_data
response_data = response_start + response_header + response_body
# 发送数据
new_socket.send(response_data)
# 6.关闭连接
new_socket.close()
def start(self):
# 4.等待客户端连接
while True:
new_socket, client_info = self.tcp_server.accept()
# 创建进程
p = Process(target=self.handle_data, args=(new_socket, client_info))
# 启动
p.start()
# 主进程关闭
new_socket.close()
def main():
web = WebServer(9998)
web.start()
if __name__ == '__main__':
main()
HTTP状态码:http://21cto.com/article/1469
一次完整的HTTP请求:https://blog.csdn.net/yipiankongbai/article/details/25029183
ALT+J 批量替换
Ctrl + P 查看函数参数提示
Alt + enter 自动生成代码
CTRL+E 打开最近的文件
CTRL+D 复制一行
CTRL+W 选中单词
CTRL+F12 用来查看方法或函数
CTRL+ALT+T
TODO:用来标注还没有完成的事情
Ctrl + 鼠标 简介/进入代码定义
Ctrl + Alt + L 代码格式化
网友评论