使用python搭建服务器

168 阅读3分钟

前提准备

  • 一个可用的端口
  • 一台不限性能的电脑
  • 一个带socketpython可执行环境(安装版和绿色版均可)

明确需求

本教程可用于搭建web服务器API服务器FTP服务器等一系列基础服务器。
教程内容较为详细,其中会提到http协议解析跨域问题解决python字符串操作多线程以及小问题解决

一、web服务器

简介

web服务器需要提供服务器路径映射,请求的答复,以及权限判定。

源码

# coding=utf-8
from socket import *
import os
def deal_post(data,data_text):
    #获取请求的地址
    url=data_text.split(' ')[1]
    if url=='/':
        url='index.html'
    #获取文件数据
    try:
        file=open(url,'r',encoding='utf-8')    
        text=file.read()
        file.close()
        print("成功访问",end='--')
    except:
        text=''
        print("文件错误:无此文件",end='--')
    #编辑头部
    header="""HTTP/1.1 200 OK\nServer: Apache/2\nAccess-Control-Allow-Origin: * \nVary: Accept-Encoding, Origin\nContent-Length: {length}\nKeep-Alive: timeout=2, max=99\nConnection: Keep-Alive\nContent-Type: text/html;charset=UTF-8\n\n{data}""".format(length=str(len(str(text).encode( 'utf-8' ))),data=text)
    #发送数据
    data.send(header.encode('utf-8'))
    print(url)
def deal_preflight(data):
    '处理跨域问题'
    header="""HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *\nAccess-Control-Allow-Methods: POST, GET, OPTIONS\nAccess-Control-Allow-Headers: X-PINGOTHER, Content-Type\nAccess-Control-Max-Age: 60\nContent-Type: text/html"""
    data.send(header.encode('utf-8'))
    pass
if __name__=="__main__":
    os.chdir('H:\掘金教程\服务器搭建')
    port=8000
    server=socket()
    #绑定服务器 ip 和端口
    server.bind(("0.0.0.0",port))
    server.setsockopt(SOL_SOCKET,SOCK_STREAM,1)
    #监听连接数
    server.listen(5)
    while True:
        data,addr=server.accept()
        #获取连接的数据
        data_text=data.recv(1024).decode('utf-8')
        #获取访问的类型
        url_type=data_text.split(' ')[0]
        
        if url_type=="OPTIONS":
            deal_preflight(data=data)
        elif url_type=="GET":
            deal_post(data=data,data_text=data_text)
        data.close()

这是一个简单的web服务器源码其中涉及到http包解析,跨域请求允许

流程简介

当你打开浏览器访问 127.0.0.1:8000 时,浏览器会向服务端发送一个GET包内容大致如下

GET包解析.png

解析:这是一个标准的http协议的GET包

  • GET 代表这个包的类型
  • / 代表这个包所请求的服务端文件地址,这里是请求默认文档,所以在服务端源码中要对应到默认文档名即index.html
  • HTTP/1.1 代表http协议的版本(一般无关紧要)
  • Host: 127.0.0.1:8000 代表客户端是访问的哪个IP,此处作用不大(在多网卡或多服务的服务器上尤为重要)
  • 后面的各种标签请到MDN web doc获取帮助

当服务器接收到这个请求就开始处理,首先服务器会获取访问的路径,然后将文件中的数据 转码再回复给浏览器。注意服务器回复内容时不是直接回复数据,你需要先回复http响应头 也就是源码中的

header="""HTTP/1.1 200 OK\nServer: Apache/2\nAccess-Control-Allow-Origin: * \nVary: Accept-Encoding, Origin\nContent-Length: {length}\nKeep-Alive: timeout=2, max=99\nConnection: Keep-Alive\nContent-Type: text/html;charset=UTF-8\n\n{data}""".format(length=str(len(str(text).encode( 'utf-8' ))),data=text)
#末尾的字符串拼接的是文件长度以及文件数据

当回复完成后,这一次浏览器请求就完美结束了。

跨域解决

在源码中的deal_preflight(data)函数就是处理跨域的结构。
处理跨域,就得了解跨域,跨域简单来说就是由于访问者端口或ip与当前页面不一致,导致浏览器拒绝访问服务器的安全措施。
解决办法:浏览器会发送一个OPTIONS类型的请求,这时只需要在响应头里加上

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 60

结束

关于API服务器FTP服务器教程留下你的评论以后再出(留下邮箱我会发送源码给你)。