简单的HTTP服务器搭建 | 手把手教你入门Python之一百一十-阿里云开发者社区

开发者社区> Python学习站> 正文

简单的HTTP服务器搭建 | 手把手教你入门Python之一百一十

简介: HTTP协议:HyperText Transfer Protocol 超文本传输协议,协议的作用就是用来传输超文本 HTML(HyperTextMarkupLanguage)。

上一篇:进程池的使用 | 手把手教你入门Python之一百零九

下一篇:Http请求头 | 手把手教你入门Python之一百一十一

本文来自于千锋教育在阿里云开发者社区学习中心上线课程《Python入门2020最新大课》,主讲人姜伟。

简单的HTTP服务器搭建

HTTP协议:HyperText Transfer Protocol 超文本传输协议
协议的作用就是用来传输超文本 HTML(HyperTextMarkupLanguage)

HTML:超文本标记语言
HTTP:用来传输超文本的一个协议

以Chrome为例,在网页空白处点击右键,选择检查,就可以显示开发者工具,其中:

  • Elements显示网页的结构
  • Network显示浏览器和服务器的通信

点Network,确保第一个小红灯亮着,Chrome就会记录所有浏览器和服务器之间的通信:

image.png

General中包含了一些概览信息,请求头和响应头在请求发送过程中的详细过程如下:

image.png

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)

在浏览器中访问结果如下:

image.png

浏览器反馈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'))

在浏览器中访问结果如下:

image.png

将代码中的地址改为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文件,然后在浏览器中访问服务器的地址的相应端口,访问效果如下:

image.png

云服务器中将打印出访问头和访问者地址信息:

image.png

此时的代码只能接收一次请求,可以在代码中添加死循环,并将端口设置方式改为动态设置:

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端口:

image.png

浏览器中访问结果:

image.png

调整返回的内容为访问者的地址:

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'))

浏览器访问效果:

image.png

配套视频

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
Python学习站
使用钉钉扫一扫加入圈子
+ 订阅

Python学习资料大全,包含Python编程学习、实战案例分享、开发者必知词条等内容。

官方博客
官网链接