上一篇:进程池的使用 | 手把手教你入门Python之一百零九
下一篇:Http请求头 | 手把手教你入门Python之一百一十一
本文来自于千锋教育在阿里云开发者社区学习中心上线课程《Python入门2020最新大课》,主讲人姜伟。
简单的HTTP服务器搭建
HTTP协议:HyperText Transfer Protocol 超文本传输协议
协议的作用就是用来传输超文本 HTML(HyperTextMarkupLanguage)
HTML:超文本标记语言
HTTP:用来传输超文本的一个协议
以Chrome为例,在网页空白处点击右键,选择检查,就可以显示开发者工具,其中:
- Elements显示网页的结构
- Network显示浏览器和服务器的通信
点Network,确保第一个小红灯亮着,Chrome就会记录所有浏览器和服务器之间的通信:
General中包含了一些概览信息,请求头和响应头在请求发送过程中的详细过程如下:
import socket
# HTTP 服务器都是基于TCP的socket链接
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('192.168.31.199', 9090))
server_socket.listen(128)
# 获取的数据是一个元组,元组里有两个元素
# 第 0 个元素是 客户端的socket链接
# 第 1 个元素是 客户端的ip地址和端口号
client_socket, client_addr = server_socket.accept()
# 从客户端的 socket 里获取数据
data = client_socket.recv(1024).decode('utf8')
# 给客户端返回消息
client_socket.send('hello world'.encode('utf8'))
print(data)
在浏览器中访问结果如下:
浏览器反馈bad response,说明需要先设置响应头
import socket
# HTTP 服务器都是基于TCP的socket链接
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('192.168.31.199', 9090))
server_socket.listen(128)
# 获取的数据是一个元组,元组里有两个元素
# 第 0 个元素是 客户端的socket链接
# 第 1 个元素是 客户端的ip地址和端口号
client_socket, client_addr = server_socket.accept()
# 从客户端的 socket 里获取数据
data = client_socket.recv(1024).decode('utf8')
print('接收到的数据{}'.format(data))
# 返回内容之前,需要先设置HTTP响应头
# 设置一个响应头就换一行
client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
client_socket.send('content-type:text/html\n'.encode('utf8'))
# 所有的响应头设置完成以后,再换行
client_socket.send('\n'.encode('utf8'))
# 发送内容
client_socket.send('hello world'.encode('utf8'))
在浏览器中访问结果如下:
将代码中的地址改为0.0.0.0:
import socket
# HTTP 服务器都是基于TCP的socket链接
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 9090))
server_socket.listen(128)
# 获取的数据是一个元组,元组里有两个元素
# 第 0 个元素是 客户端的socket链接
# 第 1 个元素是 客户端的ip地址和端口号
client_socket, client_addr = server_socket.accept()
# 从客户端的 socket 里获取数据
data = client_socket.recv(1024).decode('utf8')
print('接收到{}的数据{}'.format(client_addr[0], data))
# 返回内容之前,需要先设置HTTP响应头
# 设置一个响应头就换一行
client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
client_socket.send('content-type:text/html\n'.encode('utf8'))
# 所有的响应头设置完成以后,再换行
client_socket.send('\n'.encode('utf8'))
# 发送内容
client_socket.send('hello world'.encode('utf8'))
在云服务器中运行此py文件,然后在浏览器中访问服务器的地址的相应端口,访问效果如下:
云服务器中将打印出访问头和访问者地址信息:
此时的代码只能接收一次请求,可以在代码中添加死循环,并将端口设置方式改为动态设置:
import socket
port = int(input('请输入端口号:'))
# HTTP 服务器都是基于TCP的socket链接
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', port))
server_socket.listen(128)
print('server is running at 0.0.0.0:{}'.format(port))
# 获取的数据是一个元组,元组里有两个元素
# 第 0 个元素是 客户端的socket链接
# 第 1 个元素是 客户端的ip地址和端口号
while True:
client_socket, client_addr = server_socket.accept()
# 从客户端的 socket 里获取数据
data = client_socket.recv(1024).decode('utf8')
print('接收到{}的数据{}'.format(client_addr[0], data))
# 返回内容之前,需要先设置HTTP响应头
# 设置一个响应头就换一行
client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
client_socket.send('content-type:text/html\n'.encode('utf8'))
# 所有的响应头设置完成以后,再换行
client_socket.send('\n'.encode('utf8'))
# 发送内容
client_socket.send('hello world'.encode('utf8'))
在服务器中启动,并使用8090端口:
浏览器中访问结果:
调整返回的内容为访问者的地址:
import socket
port = int(input('请输入端口号:'))
# HTTP 服务器都是基于TCP的socket链接
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', port))
server_socket.listen(128)
print('server is running at 0.0.0.0:{}'.format(port))
# 获取的数据是一个元组,元组里有两个元素
# 第 0 个元素是 客户端的socket链接
# 第 1 个元素是 客户端的ip地址和端口号
while True:
client_socket, client_addr = server_socket.accept()
# 从客户端的 socket 里获取数据
data = client_socket.recv(1024).decode('utf8')
print('接收到{}的数据{}'.format(client_addr[0], data))
# 返回内容之前,需要先设置HTTP响应头
# 设置一个响应头就换一行
client_socket.send('HTTP/1.1 200 OK\n'.encode('utf8'))
client_socket.send('content-type:text/html\n'.encode('utf8'))
# 所有的响应头设置完成以后,再换行
client_socket.send('\n'.encode('utf8'))
# 发送内容
client_socket.send(client_addr[0].encode('utf8'))
浏览器访问效果: