Python3实现通过HTTP协议进行文件上传及下载

要实现这个功能,你需要在主机A上编写一个Python程序,该程序监听HTTP上传请求并处理上传的文件。同时,在主机B上,你可以使用任何支持HTTP POST请求的工具(如curl或浏览器插件)上传文件。

以下是一个简单的实现示例:

在主机A上的Python程序:

```python
from http.server import HTTPServer, BaseHTTPRequestHandler

class UploadHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        length = int(self.headers.get('Content-Length'))
        data = self.rfile.read(length)
        # 处理上传的文件,例如保存到本地
        print('Received file data:', data)

if __name__ == '__main__':
    # 指定监听的IP和端口
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, UploadHandler)
    print('Server started at {}:{}'.format(*server_address))
    # 开始监听HTTP请求
    httpd.serve_forever()
```

在主机B上使用curl上传文件:

```
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @/path/to/file http://<主机A的IP>:8000/upload
```

其中,`/path/to/file`是要上传的文件的本地路径,`<主机A的IP>`是主机A的IP地址。

你也可以使用其他HTTP客户端工具或浏览器插件上传文件,只需设置正确的请求头和请求体即可。


我们可以在主机A的Python程序中添加保存文件的逻辑,例如将上传的文件保存到本地磁盘上。

以下是修改后的代码示例:

```python
import os
from http.server import HTTPServer, BaseHTTPRequestHandler

UPLOAD_DIR = '/path/to/upload/directory'  # 上传文件保存的目录

class UploadHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        # 读取上传的文件数据
        content_length = int(self.headers['Content-Length'])
        file_data = self.rfile.read(content_length)
        # 从请求头中获取文件名
        filename = self.headers.get('Filename', 'unknown')
        # 保存文件到本地
        filepath = os.path.join(UPLOAD_DIR, filename)
        with open(filepath, 'wb') as f:
            f.write(file_data)
        print('Saved file to', filepath)
        # 发送响应
        self.send_response(200)
        self.end_headers()

if __name__ == '__main__':
    # 创建上传目录
    os.makedirs(UPLOAD_DIR, exist_ok=True)
    # 指定监听的IP和端口
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, UploadHandler)
    print('Server started at {}:{}'.format(*server_address))
    # 开始监听HTTP请求
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
```

在上面的代码中,我们在`do_POST`方法中添加了保存文件的逻辑。上传的文件数据存储在`self.rfile`属性中,文件名存储在请求头的`Filename`字段中。我们将上传的文件保存到`UPLOAD_DIR`目录中,并打印保存的文件路径。

你需要将`/path/to/upload/directory`替换为实际的上传目录路径。如果目录不存在,程序会自动创建它。当然,你也可以使用其他的保存文件方法,例如将上传的文件保存到数据库中。

上述代码中的HTTP服务器将一直保持运行状态,因此可以将其作为一个守护进程在主机A上运行。你可以使用`nohup`和`&`将其放入后台运行,并将输出重定向到文件中,例如:

```
nohup python3 upload_server.py > upload_server.log 2>&1 &
```

这将把服务器进程放入后台运行,并将输出保存到名为`upload_server.log`的文件中。如果需要停止服务器进程,可以使用`kill`命令将其杀死。


在上面的示例中,上传文件的URL是根据HTTP请求的路径自动生成的。如果你需要自定义上传文件的URL,可以在主机A的Python程序中使用`path`参数来指定URL路径。以下是修改后的代码示例:

```python
import os
from http.server import HTTPServer, BaseHTTPRequestHandler

UPLOAD_DIR = '/path/to/upload/directory'  # 上传文件保存的目录

class UploadHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        # 读取上传的文件数据
        content_length = int(self.headers['Content-Length'])
        file_data = self.rfile.read(content_length)
        # 获取上传的文件名
        filename = os.path.basename(self.path)
        # 保存文件到本地
        filepath = os.path.join(UPLOAD_DIR, filename)
        with open(filepath, 'wb') as f:
            f.write(file_data)
        print('Saved file to', filepath)
        # 发送响应
        self.send_response(200)
        self.end_headers()

if __name__ == '__main__':
    # 创建上传目录
    os.makedirs(UPLOAD_DIR, exist_ok=True)
    # 指定监听的IP和端口
    server_address = ('', 8000)
    # 指定上传文件的URL路径
    upload_uri = '/upload'
    httpd = HTTPServer(server_address, UploadHandler)
    httpd.upload_uri = upload_uri
    print('Server started at {}:{}{}'.format(*server_address, upload_uri))
    # 开始监听HTTP请求
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
```

在上面的代码中,我们使用`httpd.upload_uri`属性来存储上传文件的URL路径,并在启动服务器时将其打印出来。如果需要修改上传文件的URL路径,只需要修改`upload_uri`的值即可。

当客户端上传文件时,需要将文件上传到指定的URL路径,例如`http://host:port/upload`。你可以在客户端的代码中使用相同的URL路径来上传文件。


curl -X POST -H "Content-Type: application/octet-stream" --data-binary @nchome.tar.gz  http://10.168.1.197:8081

在重写`http.server.BaseHTTPRequestHandler`类中的`do_GET()`方法时,您可以使用以下函数来代表响应:

- `self.send_response()`:设置HTTP响应状态码。例如,`self.send_response(200)`表示返回一个状态码为200的HTTP响应。
- `self.send_header()`:设置HTTP响应头。例如,`self.send_header('Content-type', 'text/html')`表示设置HTTP响应头`Content-type`为`text/html`。
- `self.end_headers()`:结束HTTP响应头的设置。
- `self.wfile.write()`:将HTTP响应正文写入响应体中。例如,`self.wfile.write(b'Hello, World!')`表示将`Hello, World!`写入响应体中。

请注意,您必须以正确的顺序使用这些函数来构建完整的HTTP响应。首先,您必须使用`self.send_response()`设置HTTP响应状态码。然后,您可以使用`self.send_header()`设置HTTP响应头,然后使用`self.end_headers()`结束HTTP响应头的设置。最后,您可以使用`self.wfile.write()`将HTTP响应正文写入响应体中。

例如,以下是一个简单的示例,它从HTTP GET请求中获取请求路径和参数,并使用`self.wfile.write()`将响应正文写入响应体中:

```python
from http.server import BaseHTTPRequestHandler, HTTPServer

class MyHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # 获取请求路径和参数
        path = self.path
        params = self.headers.get('Content-Length')
        
        # 构建HTTP响应
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b'Hello, World!')

# 启动HTTP服务器
host = ''
port = 8000
httpd = HTTPServer((host, port), MyHTTPRequestHandler)
print(f'Starting server on {host}:{port}')
httpd.serve_forever()
```

在上面的示例中,`self.send_response(200)`设置HTTP响应状态码为200,`self.send_header('Content-type', 'text/html')`设置HTTP响应头`Content-type`为`text/html`,`self.end_headers()`结束HTTP响应头的设置,`self.wfile.write(b'Hello, World!')`将`Hello, World!`写入响应体中。


exit_code = result.returncode
# 检查脚本的结束码是否为0
if exit_code == 0:
print("脚本执行成功!")
else:
print("脚本执行失败,错误码为:", exit_code)
self.send_error(500)

 
 
在Python的http.server模块中,您可以使用BaseHTTPRequestHandler类来处理HTTP请求和响应。要将请求路径转换为视图函数,您需要覆盖BaseHTTPRequestHandler类中的do_GET方法,并在其中添加自定义路由逻辑。

以下是一个示例代码,其中基于不同的URL路径调用不同的视图函数:

```python
from http.server import HTTPServer, BaseHTTPRequestHandler

class MyHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(b'Hello World!')
        elif self.path == '/download':
            self.handle_download()
        else:
            self.handle_404()

    def handle_download(self):
        # logic to download a file
        self.send_response(200)
        self.send_header('Content-type', 'application/octet-stream')
        self.send_header('Content-Disposition', 'attachment; filename="example.txt"')
        self.end_headers()
        file_content = b'This is an example file.'
        self.wfile.write(file_content)

    def handle_404(self):
        self.send_error(404)

if __name__ == '__main__':
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, MyHTTPRequestHandler)
    httpd.serve_forever()
```

在此示例中,我们覆盖了BaseHTTPRequestHandler类的do_GET方法,并根据请求的URL路径调用不同的方法。例如,当请求的路径为/时,我们将发送一个Hello World!消息。当请求的路径为/download时,我们将调用handle_download方法来下载一个文件。当请求的路径不是/或/download时,我们将调用handle_404方法来发送404错误响应。

您可以根据需要添加其他路由逻辑,并在相应的处理方法中添加自定义逻辑来生成响应内容。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,Python 3支持通过HTTP协议进行文件的上传和下载操作。你可以使用内置的`http.server`模块来创建一个简单的HTTP服务器,并通过浏览器或其他HTTP客户端来上传和下载文件。 下面是一个简单的示例代码,展示了如何使用Python 3创建一个HTTP服务器,支持文件的上传和下载: ```python from http.server import HTTPServer, SimpleHTTPRequestHandler # 定义请求处理类,继承自SimpleHTTPRequestHandler class MyRequestHandler(SimpleHTTPRequestHandler): # 重写do_POST方法,处理POST请求 def do_POST(self): content_length = int(self.headers['Content-Length']) file_data = self.rfile.read(content_length) # 保存上传的文件 with open('uploaded_file.txt', 'wb') as file: file.write(file_data) self.send_response(200) self.end_headers() self.wfile.write(b'File uploaded successfully!') # 创建HTTP服务器,监听本地的8888端口 server_address = ('', 8888) httpd = HTTPServer(server_address, MyRequestHandler) # 启动服务器 print('Server running on http://localhost:8888') httpd.serve_forever() ``` 运行上述代码后,你可以通过浏览器访问`http://localhost:8888`来访问服务器。点击页面上的上传按钮,选择一个文件进行上传,上传后会在服务器上保存名为`uploaded_file.txt`的文件。 如果你想下载服务器上的文件,可以直接在浏览器中访问`http://localhost:8888/uploaded_file.txt`,浏览器会开始下载该文件。 注意:这只是一个简单的示例,使用了Python 3的内置模块,适用于简单的文件上传下载需求。对于更复杂的需求,你可能需要使用第三方库或框架来处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值