简单的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

配套视频

相关文章
|
1月前
|
缓存 算法 数据处理
Python入门:9.递归函数和高阶函数
在 Python 编程中,函数是核心组成部分之一。递归函数和高阶函数是 Python 中两个非常重要的特性。递归函数帮助我们以更直观的方式处理重复性问题,而高阶函数通过函数作为参数或返回值,为代码增添了极大的灵活性和优雅性。无论是实现复杂的算法还是处理数据流,这些工具都在开发者的工具箱中扮演着重要角色。本文将从概念入手,逐步带你掌握递归函数、匿名函数(lambda)以及高阶函数的核心要领和应用技巧。
Python入门:9.递归函数和高阶函数
|
1月前
|
开发者 Python
Python入门:8.Python中的函数
### 引言 在编写程序时,函数是一种强大的工具。它们可以将代码逻辑模块化,减少重复代码的编写,并提高程序的可读性和可维护性。无论是初学者还是资深开发者,深入理解函数的使用和设计都是编写高质量代码的基础。本文将从基础概念开始,逐步讲解 Python 中的函数及其高级特性。
Python入门:8.Python中的函数
|
1月前
|
存储 索引 Python
Python入门:6.深入解析Python中的序列
在 Python 中,**序列**是一种有序的数据结构,广泛应用于数据存储、操作和处理。序列的一个显著特点是支持通过**索引**访问数据。常见的序列类型包括字符串(`str`)、列表(`list`)和元组(`tuple`)。这些序列各有特点,既可以存储简单的字符,也可以存储复杂的对象。 为了帮助初学者掌握 Python 中的序列操作,本文将围绕**字符串**、**列表**和**元组**这三种序列类型,详细介绍其定义、常用方法和具体示例。
Python入门:6.深入解析Python中的序列
|
1月前
|
存储 SQL 索引
Python入门:7.Pythond的内置容器
Python 提供了强大的内置容器(container)类型,用于存储和操作数据。容器是 Python 数据结构的核心部分,理解它们对于写出高效、可读的代码至关重要。在这篇博客中,我们将详细介绍 Python 的五种主要内置容器:字符串(str)、列表(list)、元组(tuple)、字典(dict)和集合(set)。
Python入门:7.Pythond的内置容器
|
16天前
|
数据采集 人工智能 数据挖掘
Python 编程基础与实战:从入门到精通
本文介绍Python编程语言,涵盖基础语法、进阶特性及实战项目。从变量、数据类型、运算符、控制结构到函数、列表、字典等基础知识,再到列表推导式、生成器、装饰器和面向对象编程等高级特性,逐步深入。同时,通过简单计算器和Web爬虫两个实战项目,帮助读者掌握Python的应用技巧。最后,提供进一步学习资源,助你在Python编程领域不断进步。
|
12天前
|
缓存 负载均衡 安全
HTTP代理服务器对速度提升有何作用?
在信息化时代,网络成为生活不可或缺的一部分。HTTP代理服务器位于客户端与服务器之间,通过数据压缩、缓存机制和路由优化等方式,有效提高数据传输速度并保护个人信息安全。使用91HTTP等工具,用户可在业务需求中获得更快更安全的网络体验。
31 4
|
18天前
|
弹性计算 云计算
阿里云认证全新发布【Apsara Clouder云计算专项技能认证:云服务器ECS入门】
阿里云认证全新发布【Apsara Clouder云计算专项技能认证:云服务器ECS入门】
|
6天前
|
Docker Python 容器
Docker——阿里云服务器使用Docker部署python项目全程小记
本文记录了我在阿里云服务器上使用Docker部署python项目(flask为例)的全过程,在这里记录和分享一下,希望可以给大家提供一些参考。
|
Web App开发 前端开发 Android开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
使用MAT分析内存泄露 对于大型服务端应用程序来说,有些内存泄露问题很难在测试阶段发现,此时就需要分析JVM Heap Dump文件来找出问题。
821 0
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
总结和计划总是让人喜悦或镇痛,一方面以前一段时间没有荒废,能给现在的行动以信心,另一方面看到一年的时间并不能完成很多事情,需要抓紧时间。
639 0