You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Socket服务端向客户端传文件,如何无需手动指定文件名及扩展名?

解决Socket传输文件时自动获取文件名的方案

要实现无需手动指定文件名的文件传输,核心思路是在发送文件数据前,先把文件名等元数据传给客户端,这样客户端就能自动拿到文件名并创建对应文件保存。下面是修改后的完整实现:

服务端代码修改

import socket

def send_file_to_client(conn):
    filename = "video.mp4"
    try:
        # 1. 先发送文件名的字节长度(用4字节固定长度,方便客户端解析)
        filename_bytes = filename.encode('utf-8')
        conn.send(len(filename_bytes).to_bytes(4, byteorder='big'))
        # 2. 发送文件名内容
        conn.send(filename_bytes)
        # 3. 发送文件数据
        with open(filename, 'rb') as file:
            while chunk := file.read(4096):
                conn.send(chunk)
        print("文件发送完成")
    except FileNotFoundError:
        print(f"错误:未找到文件 {filename}")
        # 发送空长度表示文件不存在,告知客户端
        conn.send(b'\x00\x00\x00\x00')
    except Exception as e:
        print(f"发送文件时出错:{e}")

客户端代码修改

import socket

def recvfile(soc):
    try:
        # 1. 先接收文件名的字节长度(4字节)
        filename_len_bytes = soc.recv(4)
        if not filename_len_bytes:
            print("连接已断开")
            return
        filename_len = int.from_bytes(filename_len_bytes, byteorder='big')
        if filename_len == 0:
            print("服务端告知文件不存在")
            return
        # 2. 接收文件名内容
        filename_bytes = soc.recv(filename_len)
        filename = filename_bytes.decode('utf-8')
        # 3. 接收文件数据并写入
        with open(filename, 'wb') as file:
            while True:
                chunk = soc.recv(4096)
                if not chunk:
                    break
                file.write(chunk)
        print(f"文件 {filename} 下载完成")
    except Exception as e:
        print(f"接收文件时出错:{e}")

关键细节说明

  • 使用4字节固定长度传递文件名长度:这样客户端能准确知道接下来要接收多少字节的文件名,避免和后续的文件数据混淆,比用分隔符(比如\n)更可靠,尤其是文件名本身可能包含特殊字符时。
  • 加入了基础的异常处理:比如服务端找不到文件时,会给客户端发送标识,避免客户端一直等待;同时捕获通用异常,提升代码健壮性。
  • 使用with语句操作文件:自动管理文件句柄,避免忘记关闭文件导致的资源泄漏。

内容的提问来源于stack exchange,提问作者user11487132

火山引擎 最新活动