简单的 HTTP 服务器搭建 | 学习笔记

简介: 快速学习简单的 HTTP 服务器搭建,介绍了简单的 HTTP 服务器搭建系统机制, 以及在实际应用过程中如何使用。

开发者学堂课程【Python 入门 2020年版简单的 HTTP 服务器搭建】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/639/detail/10477


简单的HTTP服务器搭建

 

内容介绍:

一、学习目标

二、使用谷歌/火狐浏览器分析

三、概念

四、结合实例百度网站编写服务器

 

一、学习目标

1.能够说出什么是 HTTP 协议

2.能够手写代码搭建一个 HTTP 服务器

3.了解 WSGI 接口

4.能够看懂自定义 WSGI 服务器

5.能够使用requests插件发送请求

今天学习搭建网站,但是这个网站能力差、功能不全、性能不好,只是简单讲一下框架的实现理论。

 

二、使用谷歌/火狐浏览器分析

1.在 Web 应用中,服务器把网页传给浏览器,实际上就是把网页的 HTML 代码发送给浏览器,让浏览器显示出来。而浏览器和服务器之间的传输协议是 HTTP,所以:

HTML 是种用来定义网页的文本,会 HTML, 就可以编写网页;

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

Chrome 浏览器提供了一套完整地调试工具,非常适合 Web 开发。

安装好 Chrome 浏览器后,打开 Chrome,在菜单中选择"视图",“开发者", “开发者工具", 就可以显示开发者工具: 

2.说明

Elements 显示网页的结构

Network 显示浏览器和服务器的通信

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


三、概念

HTTP 协议:Hyper Text Transfer Protocol 超文本传输协议

协议的作用就是用来传输超文本 HTML(Hyper Text Markup Language)

HTML:超文本标记语言

HTTP:用来传输超文本的一个协议

有什么规则

我们上网是干什么,怎么写一个网站呢

客户端 Client

HTTP 服务器 Server

C/S架构 client-server    手机淘宝 APP 就是一个客户端

B/S架构 browser-server  浏览器访问淘宝

不管是 APP 还是浏览器我们都可以把它们看作客户端。不管是什么结构就是客户端不一样,服务器的实现都是一样的,返回的数据也是一样的。

如果前后端分离就返回 json 字符串,比如’{“name”:”zhangsan ”}’

图片7.png


四、结合实例百度网站编写服务器

在浏览器里输入192.168.31.199,是不能正常访问操作的。

上网,两个电脑要通信就是网络通信,用 socket 写,其实就是 socket 链接。

1.代码:

import socket

#HTTP服务器都是基于TCP的socket

server_socket=socket.socket(socket.AF_INEF, socket.SOCK_STREAM)

server_socket.bind((‘192.168.31.199’,9090))

server_socket.listen(128)

x=server_socket.accept()

print(x)

用网络调试助手连接一下,会收到消息,获取的数据是一个元祖,元祖里有两个元素,第0个元素是客户端的socket链接,第1个元素是客户端的ip地址和端口号。

2.代码:

import socket

#HTTP服务器都是基于TCP的socket

server_socket=socket.socket(socket.AF_INEF, 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(data)

在网络调试助手,数据发送处发送 ok,就能在写的服务器中收到 ok。要对底层开发有所认识,但以后写不会用 socket。

128是什么意思,当服务器能够处理1000个,但如果突然同时来了1002个,那这两个就处理不了,需要排队,如果来了1120个,120个也要排队,如果来了1130个,有130个不能处理,128就是排队的长度,剩下的2个就连不进来了。

刚才用网络调试工具访问了服务器,发消息,那能不能用代码发送,以前写过用代码发送一个TCP的请求,自己写了一个服务器。

现在不用客户端,用浏览器。程序已经运行到192.168.31.199:9090(9090是端口号),这里可以用网络调试工具访问,只要能发送一个请求就可以,我们也可以自己写代码发送请求,也能使用浏览器发送请求。

 图片8.png

用浏览器是可以收到请求的

图片9.png

图片10.png

上图是 HTTP 的请求头

打开控制栏的两种方法(使用的谷歌浏览器):

(1)右击找到检查

图片11.png

 

2右上角找到浏览器的设置——更多工具——开发者工具

图片12.png

打开后如下图:

图片13.png

先把控制栏打开,这有 Elements,它是界面上的元素。比如打开百度新闻点击一个内容控制栏就会标对应的代码,右击代码选择“delete element”就能删除对应内容,但不是真正删除,只是在自己界面上的元素,刷新删除的元素就会恢复。

我们今天要关注的重点是 network,访问网站时我们发了好多个请求,其中有一个是 www.baidu.com,有的时候我们打开以后会没有了,只需要重新刷新网站,然后再右击检查打开控制栏。经常会发现 network 没有东西,原因是网络没有连接,再刷新一下页面就可以看到了。进入“www.baidu.com”,其中“General”是概要、通用的东西,大家可以简单地看一看,我们先不看这个,先把它收起来。里面有“General”、“Response Headers”、“Request Headers”,后两个分别是“响应头”和“请求头”。

 图片14.png

 图片15.png

也就是说发的要有规范,返回的也要有规范。

服务器没有给客户端返回消息,9090是空的。

怎么给客户端返回消息:

import socket

#HTTP服务器都是基于TCP的socket

server_socket=socket.socket(socket.AF_INEF, 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)

这时我们运行一下能不能收到

图片16.png

返回内容之前,需要先设置 HTTP 响应头

怎么设置呢,我们先看一下标准的实例:

点击“view source”(在没点“view source”时,显示的是解析后的内容)就可以看到它的响应头。

图片17.png

import socket

#HTTP服务器都是基于TCP的socket

server_socket=socket.socket(socket.AF_INEF, 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’))  #HTTP/1.1 200 OK是必须写的,是格式

#所有的响应头设置完成以后,再换行

client_socket.send(‘\n’.encode(‘utf8’))

#发送内容

client_socket.send(“hello world”.encode(‘utf8’))

运行结果:

图片18.png

再加一个响应头:client_socket.send(‘content-type:text/html’.encode(‘utf8’))

每一个头写完以后都要换行,所有的头写完以后再来一个换行,紧跟着才是消息。

import socket

#HTTP 服务器都是基于 TCP 的 socket

server_socket=socket.socket(socket.AF_INEF, 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))

OK 是必须写的,是格式

client_socket.send(‘content-type:text/html’.encode(‘utf8’))

#所有的响应头设置完成以后,再换行

client_socket.send(‘\n’.encode(‘utf8’))

#发送内容

client_socket.send(“hello world”.encode(‘utf8’))

运行结果:同上,出现 hello world。

这个代码是放在自己电脑上的,我现在把它放到更大的地方,放到腾讯的云服务器上。

但注意地址要改成‘0.0.0.0’,端口号不能写死,地址的区别一会再讲。

运行起来:

图片19.png

我的云端服务器的 ip 地址是:106.54.81.174:9090

可以访问到 hello world

这个不止是我能访问,同学们也能访问,但是我这服务器是一次性的,一次就崩。

修改一下代码:

import socket

#HTTP服务器都是基于TCP的socket

server_socket=socket.socket(socket.AF_INEF, socket.SOCK_STREAM)

server_socket.bind((‘0.0.0.0’,8080))

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’))  #HTTP/1.1 200 OK是必须写的,是格式

client_socket.send(‘content-type:text/html’.encode(‘utf8’))

#所有的响应头设置完成以后,再换行

client_socket.send(‘\n’.encode(‘utf8’))

#发送内容

client_socket.send(“hello world”.encode(‘utf8’))

现在同学们可以输入地址:106.54.81.174:8080可以访问到 hello world

再改成9090也可以访问到,我这个代码只能接收一次,我没有写死循环,一个同学访问到,其他同学就访问不到了。

换一下端口号,写个死循环:

import socket

port=int(input(‘请输入端口号:’))

#HTTP 服务器都是基于 TCP 的 socket

server_socket=socket.socket(socket.AF_INEF, 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’))  #HTTP/1.1 200 OK 是必须写的,是格式

client_socket.send(‘content-type:text/html’.encode(‘utf8’))

#所有的响应头设置完成以后,再换行

client_socket.send(‘\n’.encode(‘utf8’))

#发送内容

client_socket.send(“hello world”.encode(‘utf8’))

现在把代码上传到服务器,让大家玩一玩,原理还是很简单的。

图片20.png

是可以访问到的,端口号我改成9090,不断变,因为一直提示占用,这个服务器比较脆弱。

现在不返回 hello world,我把你们的 ip 地址返回去。不只是电脑可以访问,手机也可以。

图片21.png

 

相关文章
|
1月前
使用Netty实现文件传输的HTTP服务器和客户端
本文通过详细的代码示例,展示了如何使用Netty框架实现一个文件传输的HTTP服务器和客户端,包括服务端的文件处理和客户端的文件请求与接收。
35 1
使用Netty实现文件传输的HTTP服务器和客户端
|
7天前
|
存储 Oracle 关系型数据库
oracle服务器存储过程中调用http
通过配置权限、创建和调用存储过程,您可以在Oracle数据库中使用UTL_HTTP包发起HTTP请求。这使得Oracle存储过程可以与外部HTTP服务进行交互,从而实现更复杂的数据处理和集成。在实际应用中,根据具体需求调整请求类型和错误处理逻辑,以确保系统的稳定性和可靠性。
9 0
|
2月前
|
前端开发 JavaScript
|
2月前
|
开发者
HTTP状态码是由网页服务器返回的三位数字响应代码,用于表示请求的处理结果和状态
HTTP状态码是由网页服务器返回的三位数字响应代码,用于表示请求的处理结果和状态
31 1
|
3月前
|
缓存 数据安全/隐私保护 UED
代理服务器在HTTP请求中的应用:Ruby实例
代理服务器在HTTP请求中的应用:Ruby实例
|
4月前
|
存储 运维 Java
函数计算产品使用问题之如何使用Python的requests库向HTTP服务器发送GET请求
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
104 8
|
3月前
|
移动开发 网络协议 编译器
实战案例3:C语言实现的HTTP服务器
实战案例3:C语言实现的HTTP服务器
150 0
|
4月前
|
缓存 程序员 开发者
HTTP状态码大全:如何读懂服务器的语言?
大家好,我是小米,今天我们来聊聊HTTP协议中的GET和POST请求。它们在数据传输方式、安全性和应用场景上有不同特点。本文将详细解析它们的区别和特点,帮助你更好地理解和运用这两种请求方式。让我们一起学习吧!
69 1
|
4月前
|
Shell Python
`pytest-httpserver`是一个pytest插件,它允许你在测试期间启动一个轻量级的HTTP服务器,并模拟HTTP请求和响应。
`pytest-httpserver`是一个pytest插件,它允许你在测试期间启动一个轻量级的HTTP服务器,并模拟HTTP请求和响应。
|
4月前
|
网络协议 安全 Python
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
我们将使用Python的内置库`http.server`来创建一个简单的Web服务器。虽然这个示例相对简单,但我们可以围绕它展开许多讨论,包括HTTP协议、网络编程、异常处理、多线程等。
下一篇
无影云桌面