zoukankan      html  css  js  c++  java
  • Python之HTTP静态Web服务器开发

    众所周知,Http协议是基于Tcp协议的基础上产生的浏览器到服务器的通信协议 ,其根本原理也是通过socket进行通信。

     使用HTTP协议通信,需要注意其返回的响应报文格式不能有任何问题。

    响应报文,一共包括4个部分,分别是响应行,响应头,空行,响应体,并且每项数据之间必须使用/r/n隔开。

    空行是区分响应头和响应体的必要数据,不能省略。

    HTTP静态Web服务器主要开发思路如下:

    1.导入socket模块

    2.创建socket对象

    3.设置端口复用,解决端口阻塞问题

    4.绑定端口及ip,在绑定端口及IP后,客户端只能通过绑定的IP及端口给服务器发送请求报文。

    5.设置监听,

    注意:设置监听成功后,原socket变成被动套接字,不能够进行数据的收发。

    6.等待客户端(浏览器)链接(发送请求)

    7.使用链接成功后返回的新socket进行数据的收发。

    注意:此处返回数据应为HTTP响应报文。

     1 # 1.导入模块
     2 import socket
     3 
     4 
     5 def main():
     6     # 2.创建socket对象
     7     server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     9     # 3.设置端口复用
    10     server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    11     # 4.绑定端口
    12     server_socket.bind(('', 8001))
    13     # 5.设置监听
    14     server_socket.listen(128)
    15     # 设置循环接收客户端连接,实现多客户端连接
    16     while True:
    17         # 6.接收客户端连接
    18         client_socket, ip_port = server_socket.accept()
    19         print("客户端:%s 上线了,使用端口为:%s" % ip_port)
    20         # 7.接收数据
    21         recv_data = client_socket.recv(1024).decode('utf-8')
    22         if recv_data:
    23             # print('接收的数据为:', recv_data)
    24             # 获取http请求报文中的指定路径
    25             # split()方法不指定参数时,默认以空白字符(	,
    ,空格)分割
    26             # 获取到的路径信息分割后,会形成三部分存放到列表中
    27             # 1.请求提交的方式:GET/POST
    28             # 2.请求路径信息及参数信息
    29             # 3.HTTP协议及版本
    30             page_recv_data = recv_data.split()[1]
    31             print('请求的资源路径为:', page_recv_data)
    32             # 判断接受到的路径信息是否包含参数
    33             # HTTP协议中,参数格式为:/index.html?name=666&age=12
    34             if '?' in page_recv_data:
    35                 real_recv_page = page_recv_data.split('?')[0]
    36             else:
    37                 real_recv_page = page_recv_data
    38             try:
    39                 # 8.发送数据
    40 
    41                 # 接收指定的路径信息,并读取文件信息
    42                 # 注意f-string只能在3.6及以上版本使用
    43                 data = f'static{real_recv_page}'
    44                 print(data)
    45                 with open(data, 'rb') as file:
    46                     page_data = file.read()
    47             except Exception as e:
    48                 # 8.1 当文件不存在时,编写HTTP协议如下格式:
    49                 http_line = 'HTTP/1.1 / 404 NOT FOUND
    '
    50                 http_header = 'Server: PWS/1.0
    '
    51                 http_body = '<h1>Page Not Found!</h1>'
    52                 send_data = (http_line + http_header + '
    ' + http_body).encode()
    53                 client_socket.send(send_data)
    54             else:
    55                 # 8.1 当文件存在时,编写HTTP协议如下格式:
    56                 http_line = 'HTTP/1.1 / 200 ok
    '
    57                 http_header = 'Server: PWS/1.0
    '
    58                 send_data = (http_line + http_header + '
    ').encode() + page_data
    59                 client_socket.send(send_data)
    60             finally:
    61                 # 断开与客户端连接
    62                 client_socket.close()
    63         else:
    64             print('客户端:%s,端口号:%s 下线了' % ip_port)
    65             break
    66 
    67     # 9.关闭套接字
    68     # 关闭服务器
    69     # server_socket.close()
    70 
    71 
    72 # 入口
    73 if __name__ == '__main__':
    74     main()
    该花的钱要花,该吃的饭要吃。
  • 相关阅读:
    .NetCore 导出Execl
    10块钱可以喝几瓶?
    menuStrip鼠标滑过自动弹出
    静态变量
    DataTable.SELECT日期类型筛选处理
    Java中accept()阻塞是如何实现的
    L1正则在0处不可导怎么办?
    L1和L2正则化原理推导.md
    5局3胜和3局2胜哪个更容易赢.md
    Java集合(一): 集合框架Collection和Map
  • 原文地址:https://www.cnblogs.com/chao666/p/12008315.html
Copyright © 2011-2022 走看看