手动搭建服务器—Python
目录
1.HTTP协议
2.HTTP请求头
3.IP地址的绑定
4.根据不同的请求返回不同的内容
5.面向对象的服务器封装
6.WSGI服务器
6.1 WSGI接口
6.2 WSGI不同路径返回不同内容
6.3 读取文件并加载返回给浏览器
6.4 方法的封装
6.5 requests模块的使用
1.HTTP协议
HTTP协议:HyperText Transfer Protocol 超文本传输协议
协议的作用:就是用来传输超文本(HTML:HyperTextMarkupLanguage超文本标记语言)HTML:超文本标记语言
HTTP:用来传输超文本的一个协议
C/S架构:client-server 手机淘宝APP
B/S架构:browser-server 浏览器访问淘宝
在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来。而浏览器和服务器之间的传输协议是HTTP,所以:
- HTML是一种用来定义网页的文本,会HTML,就可以编写网页;
- HTTP是在网络上传输HTML的协议,用于浏览器和服务器的通信。
Chrome浏览器提供了一套完整地调试工具,非常适合Web开发。
安装好Chrome浏览器后,打开Chrome,在菜单中选择“视图”,“开发者",“开发者工具”,就可以显示开发者工具。
import socketport=int(input('请输入端口号:'))
n=int(input('请输入您允许访问该网站的次数:'))
#HTTP 服务器都是基于TCP的socket连接
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.bind(('192.168.1.223',port))
server_socket.listen(128)
print('server is running ar 192.168.1.223:{}'.format(port))
#获取到数据时一个元组
#第0个元素:客户端的socket连接
#第1个元素:客户端的ip和端口号while n:n-=1client_socket,client_addr=server_socket.accept()#从客户端的socket中获取数据data=client_socket.recv(1024)print('接收到了来自{}地址{}端口号的的信息,内容是:{}'.format(client_addr[0],client_addr[1],data.decode('gbk')))#在返回内容之前需要设置HTTP响应头#设置一个响应头就换一行client_socket.send('HTTP/1.1 200 OK\n'.encode('gbk'))client_socket.send('content-type:text/html\n'.encode('gbk'))#所有的响应头设置完成后再换行client_socket.send('\n'.encode('gbk'))#给客户端的返回消息client_socket.send(client_addr[0].encode('gbk'))
运行结果:
2.HTTP请求头
"""
#GET 请求方式,GET/POST/PUT/DELETE...
#/index.html 请求的路径
#HTTP/1.1 HTTP的版本号GET / HTTP/1.1
Host: 192.168.1.223:8080 #客户端请求的服务器地址
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1#UA 用户代理,设计目的是为了能从请求头里辨识浏览器的类型
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.66 Safari/537.36 Edg/103.0.1264.44
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
"""
3.IP地址的绑定
#IP地址能够通过IP地址访问
#server_socket.bind(('192.168.1.223', 8080))
#能够通过127.0.0.1 和localhost(只有局域网内的主机才可以访问) 来访问
#127.0.0.1 和0.0.0.0都表示本机 0.0.0.0表示所有的可用的地址
server_socket.bind(('127.0.0.1', 8080))
4.根据不同的请求返回不同的内容
import socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind(('127.0.0.1', 8080))server_socket.listen(128)
print('server is running ar 192.168.1.223:{}'.format(8080))while True:client_socket, client_addr = server_socket.accept()data = client_socket.recv(1024).decode('gbk')#浏览器发送的数据有可能是空的#print('接收到了来自{}地址{}端口号的的信息,内容是:{}'.format(client_addr[0], client_addr[1], data))path = ''if data:path=data.splitlines()[0].split()[1]#切字符串print('请求的路径是:{}'.format(path))# 响应体response_body = 'hello zmj!'# 响应头response_header = 'HTTP/1.1 200 OK\n' # 200是OK状态码if path=='/login':response_body='欢迎来到登录页面!'elif path=='/register':response_body='欢迎来到注册页面'elif path=='/':response_body='欢迎来到首页'else:#页面没找到 404 Page Not Foundresponse_header = 'HTTP/1.1 404 Page Not Found\n' # 200是OK状态码response_body='对不起,您要查找的页面不存在!!!'response_header+='content-type:text/html;charset=utf8\n'response_header+='\n'#响应response=response_header+response_body#发送给客户端client_socket.send(response.encode('utf8'))
运行结果:
5.面向对象的服务器封装
import socketclass MyServer(object):def __init__(self,ip,port):self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)self.socket.bind((ip,port))self.socket.listen(128)def run_forever(self):while True:client_socket, client_addr = self.socket.accept()data = client_socket.recv(1024).decode('gbk')path = ''if data:path = data.splitlines()[0].split()[1] # 切字符串response_body = 'hello zmj!'response_header = 'HTTP/1.1 200 OK\n' # 200是OK状态码if path == '/login':response_body = '欢迎来到登录页面!'elif path == '/register':response_body = '欢迎来到注册页面'elif path == '/':response_body = '欢迎来到首页'else:response_header = 'HTTP/1.1 404 Page Not Found\n' # 200是OK状态码response_body = '对不起,您要查找的页面不存在!!!'response_header += 'content-type:text/html;charset=utf8\n'response_header += '\n'response = response_header + response_bodyclient_socket.send(response.encode('utf8'))server=MyServer('127.0.0.1',8080)
server.run_forever()
6.WSGI服务器
6.1 WSGI接口
WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求。我们来看一个最简单的Web版本的“Hello, web!”:
def application(environ,start_response):start_response('200 OK',[('Content-Type','text/html')]return '<h1>Hello,web!</h1>'
上面的application()函数就是符合WSGI标准的一个HTTL处理函数,它接收两个参数:
- environ:一个包含所有的HTTL请求信息的dict对象;
- start_response:一个发送HTTP响应的函数
在application()函数中调用:start_response('200 OK',[('Content-Type','text/html')],就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。start_response()函数调用两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每个Header用一个包含两个str的tuple表示。
通常情况下,都应该把Content-Type头发送给浏览器,其他很多常用的HTTP Header也应该发送。
代码一:
#直接使用库里面的import webbrowser
from wsgiref.simple_server import make_server, demo_appif __name__=='__main__':httpd=make_server('',8000,demo_app)sa=httpd.socket.getsockname()print('Serving HTTP on',sa[0],'port',sa[1],'...')webbrowser.open('http://localhost:8000/xyz?abc')httpd.serve_forever()
结果:
代码二:
#自定义显示内容import webbrowser
from wsgiref.simple_server import make_server#demo_app需要两个参数,
#第1个参数:表示环境(电脑的环境;请求路径的相关的环境)
#第2个参数:是一个函数,用于返回响应头
#需要返回值,返回值是一个列表,列表中只有一个元素,是一个二进制,表示返回给浏览器的数据
def demo_app(environ,start_response):#environ 是一个字典,保存了很多数据#其中重要的一个是PATH_INFO能够获取到用户的访问路径path=environ['PATH_INFO']print('path={}'.format(path))#start_response第一个参数是状态码,第二个是响应头start_response('200 OK',[('Content-Type','text/html;charset=utf8')])return ['hello'.encode('utf8')]#浏览器显示的内容if __name__=='__main__':#demo_app是一个函数,用来处理用户的请求#8000是一个端口号httpd=make_server('',8000,demo_app)sa=httpd.socket.getsockname()print('Serving HTTP on',sa[0],'port',sa[1],'...')#作用:打开电脑的浏览器,并在浏览器中输入'http://localhost:8000/xyz?abc'#也可以手动打开webbrowser.open('http://localhost:8000/xyz?abc')# 只处理一个请求,然后退出#httpd.handle_request()httpd.serve_forever()#服务器在后台一直运行
结果:
6.2 WSGI不同路径返回不同内容
# 状态码:RSETFUL ==>前后端分离
# 2XX:请求响应成功
# 3XX:重定向
# 4XX:客户端的错误。 404:客户端访问了一个不存在的地址 405:请求方式不被允许
# 5XX:服务器的错误。
import webbrowser
from wsgiref.simple_server import make_server#demo_app需要两个参数,
#第1个参数:表示环境(电脑的环境;请求路径的相关的环境)
#第2个参数:是一个函数,用于返回响应头
#需要返回值,返回值是一个列表,列表中只有一个元素,是一个二进制,表示返回给浏览器的数据
def demo_app(environ,start_response):#environ 是一个字典,保存了很多数据#其中重要的一个是PATH_INFO能够获取到用户的访问路径path=environ['PATH_INFO']status_code='200 OK'#默认状态码是200if path=='/':response='欢迎来到我的首页'elif path=='/text':response='欢迎来到张梦姣的页面'elif path=='/demo':response='欢迎来到demo页面'else:response='页面走丢了!'#如果页面出问题了,status_code='404 Not Found'#start_response第一个参数是状态码,第二个是响应头start_response(status_code,[('Content-Type','text/html;charset=utf8')])return [response.encode('utf8')]#浏览器显示的内容if __name__=='__main__':#demo_app是一个函数,用来处理用户的请求#8000是一个端口号httpd=make_server('127.0.0.1',8080,demo_app)#这里第一个参数是地址,空表示是'0.0.0.0'sa=httpd.socket.getsockname()print('Serving HTTP on',sa[0],'port',sa[1],'...')#作用:打开电脑的浏览器,并在浏览器中输入'http://localhost:8000/xyz?abc'#也可以手动打开#webbrowser.open('http://localhost:8000/xyz?abc')# 只处理一个请求,然后退出#httpd.handle_request()httpd.serve_forever()#服务器在后台一直运行
去掉注释的代码:
import webbrowser
from wsgiref.simple_server import make_serverdef demo_app(environ,start_response):path=environ['PATH_INFO']status_code='200 OK'#默认状态码是200if path=='/':response='欢迎来到我的首页'elif path=='/text':response='欢迎来到张梦姣的页面'elif path=='/demo':response='欢迎来到demo页面'else:response='页面走丢了!'#如果页面出问题了,status_code='404 Not Found'start_response(status_code,[('Content-Type','text/html;charset=utf8')])return [response.encode('utf8')]if __name__=='__main__':httpd=make_server('127.0.0.1',8080,demo_app)sa=httpd.socket.getsockname()print('Serving HTTP on',sa[0],'port',sa[1],'...')httpd.serve_forever()
结果:
6.3 读取文件并加载返回给浏览器
import json
import webbrowser
from wsgiref.simple_server import make_serverdef demo_app(environ,start_response):path=environ['PATH_INFO']#print(environ.get('QUERY_STRING'))#query_string ==>获取到客户端GET请求方式传递的参数status_code='200 OK'if path=='/':response='欢迎来到我的首页'elif path=='/test':response=json.dumps({'name':'zhangsan','age':20,'gender':'male'})elif path=='/demo':with open('./pages/xxxx.txt','r',encoding='utf8') as file:response = file.read()elif path=='/hello':with open('./pages/hello.html', 'r', encoding='utf8') as file:response = file.read()elif path=='/info':#查找数据库,获取到用户名name='Tom'with open('./pages/info.html', 'r', encoding='utf8') as file:#flash django 模板,渲染引擎response = file.read().format(username=name)#读取的就是字符串else:response='页面走丢了!'#如果页面出问题了,status_code='404 Not Found'#start_response第一个参数是状态码,第二个是响应头start_response(status_code,[('Content-Type','text/html;charset=utf8')])return [response.encode('utf8')]#浏览器显示的内容if __name__=='__main__':httpd=make_server('127.0.0.1',8080,demo_app)sa=httpd.socket.getsockname()print('Serving HTTP on',sa[0],'port',sa[1],'...')httpd.serve_forever()#服务器在后台一直运行
hello.html文件里面的内容:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>.box{margin:0 auto;}.div{width:1000px;}.top{height:80px;background-color:red;margin-bottom:10px;}.middle{height:400px;}.left{width:100px;height:100%;background-color:yellow;float:left;margin-right:10px;}.content{width:970px;height:100%;background-color:pink;float:left;margin-right:10px;}.right{width:100px;height:100%;background-color:blue;float:right;}.bottom{height:80px;background-color:lime;margin-top:10px;}</style>
</head>
<body>
<div class="box"><div class="middle"><div class="left"></div><div class="content"></div><div class="right"></div></div><div class="bottom"></div>
</div></body>
</html>
info.html文件里面的内容:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
{username},欢迎回来,
</body>
</html>
前端结果:
6.4 方法的封装
import json
import webbrowser
from wsgiref.simple_server import make_serverdef load_html(file_name):try:with open('./pages/'+file_name,'r',encoding='utf8') as file:content=file.read()return contentexcept FileNotFoundError:print(file_name,'文件没找到!')def index():return '欢迎来到我的首页'def show_test():return json.dumps({'name':'zhangsan','age':20,'gender':'male'})def show_demo():return load_html('xxxx.txt')def show_hello():return load_html('hello.html')def show_info():# 查找数据库,获取到用户名name = 'Tom'return load_html('info.html').format(username=name)url={'/':index,'/test':show_test,'/demo':show_demo,'/info':show_info,'/hello':show_hello()
}
def demo_app(environ,start_response):path=environ['PATH_INFO']status_code='200 OK'method=url.get(path)if method:response=method()else:response = '页面走丢了!' # 如果页面出问题了,status_code = '404 Not Found'start_response(status_code,[('Content-Type','text/html;charset=utf8')])return [response.encode('utf8')]if __name__=='__main__':httpd=make_server('127.0.0.1',8000,demo_app)sa=httpd.socket.getsockname()print('Serving HTTP on',sa[0],'port',sa[1],'...')httpd.serve_forever()
6.5 requests模块的使用
作用就是模拟浏览器,获取请求的功能。
#requests模块是第三方的模块,可以用来发送网络连接
import requests
response=requests.get('http://127.0.0.1:8000')#注意:这个路径需要写http
print(response)#<Response [200]> ==> 结果是一个Response对象
print(response.content.decode('utf8'))#"欢迎来到我的首页" ==> 获取的内容,返回的是一个二进制(可以用来传递图片),需要decode
print(response.text,' 类型:',type(response.text))#'欢迎来到我的首页' ==> 结果就是字符串,不需要decode
print(response.status_code)#200 ==> 获取状态码#若果返回的结果是json串,就用这个解析
#print(response.json())#json的返回类型不是字符串,而是原数据类型
运行结果:
手动搭建服务器—Python相关推荐
- Python 3 怎么快速搭建服务器
Python 3 怎么快速搭建服务器 python 3 环境,我就不多说了 1.新建一个文件夹 2.放文件夹里一个 index.html 文件用来默认访问,不然会炸的 3.进入文件目录 4.执行以下命 ...
- python搭建内网网站,python搭建服务器
python搭建服务器 python搭建服务器以快捷著称,实际上,我们也可以使用python搭建简易的服务器. 1.环境配置 当然首先得搭建python的开发环境,对于mac和linux的用户来说,一 ...
- python服务器环境搭建_服务器python环境搭建
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! python搭建服务器以快捷著称,实际上,我们也可以使用python搭建简易的服 ...
- 腾讯云服务器如何手动搭建LAMP环境?
LAMP 环境是指 Linux 系统下,由 Apache + MariaDB + PHP 及其它相关辅助组件组成的网站服务器架构.本文本文档介绍如何在腾讯云云服务器(CVM)上手动搭建 LAMP 环境 ...
- 腾讯云服务器CVM(CentOS 7、Tencent Linux)手动搭建LNMP环境(linux+Nginx+Mariadb+PHP)
手动搭建云服务器运行环境就是喜欢折腾,如果觉得麻烦的网友可以使用LNMP镜像直接启动CVM实例,以便快速建站. 腾讯云服务器CVM(CentOS 7.Tencent Linux)手动搭建LNMP环境( ...
- python+Linux centos7搭建服务器
我是一个前端出身的,所以搭建服务器环境费了几天,参考了大量资料,现在终于完成了,写一下总结 1.安装python3.X 参考:https://blog.csdn.net/zhangdongren/ar ...
- 手动搭建HPC(高性能计算)
撰写日期:2017年6月13日 作者:翟江恒 一般情况下不会采用手动的方式安装HPC,而是采用集成自动化方案来部署hpc,但是这些集成方案都是集成了指定的操作系统发行版本,比如常见的HPC集成自动化方 ...
- ubuntu下git搭建服务器(gitosis)
ubuntu下git搭建服务器(gitosis) - 简书 var _hmt = _hmt || []; (function() { var hm = document.createElement(& ...
- 手动搭建PHP开发环境
前言 准备工作 安装 安装Python 安装MySQL服务器 安装PHP环境 安装Apache 参考资料 前言 额...虽然网上有人发过了,不过都是相对来讲老一些的版本了... 我要进行搭建的版本是: ...
最新文章
- mysql 选项_mysql常用选项
- 关于java线程同步的笔记_线程同步(JAVA笔记-线程基础篇)
- 老郭的《Dalvik虚拟机垃圾收集机制简要介绍和学习计划》
- HDU 3709 Balanced Number (数位DP)
- 二叉树的建立与遍历_51、二叉树遍历-重建二叉树JZ4
- 前端学习(3295):清除effect
- 函数体中定义的结构体和类型
- Vue中拆分视图层代码的5点建议
- 19【推荐系统19】SNR:多任务学习
- 移动光猫搭建虚拟服务器,折腾光猫/路由器[MIPS架构](1):用Samba服务器搭建家庭文件共享中心...
- python读取csv最后一行_用Python读取CSV文件行的最后一个非空单元格
- 如何修改PDF文件的标题
- 《GKT:Efficient and Robust 2D-to-BEV Representation Learning via Geometry-guided Kernel Transformer》
- 【动手学深度学习】(task123)注意力机制剖析
- 无线鼠标 桌面服务器,你可能不知道 桌面总是乱糟糟的很可能是因为你没买对鼠标...
- 树莓派python图形化编程_BlockPi: 树莓派图形化编程软件,轻松控制GPIO、SenseHAT、Picamera等硬件。...
- Icon图标制作(转化)工具
- 设计模式六大设计原则 详细整理版
- 关于校外访问西安电子科技大学校内图书馆资源和教务系统等的方法总结
- hackthebox(HTB) precious 靶机!