You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Socket的Python FTP传输脚本:传输成功但目标服务器无文件

问题诊断与解决方案

为啥文件传了却找不到?

你写的脚本根本没遵循FTP协议规则,导致vsftpd完全识别不了你发的是要保存的文件:

  • FTP分控制连接(端口21)和数据连接:控制连接只用来发命令(比如登录、上传指令),文件内容得通过单独的数据连接传输,你直接在控制连接里塞文件数据,服务器只会把这些当乱码,不会存成文件。
  • 缺失关键命令:上传文件必须先告诉服务器「我要传二进制文件」(TYPE I)、「建立数据连接」(PASV或PORT)、「我要传这个文件,名叫XXX」(STOR 文件名),你脚本里完全没这些步骤。
  • 无效的文件标识:你发的{file_path}{filesize}格式服务器根本看不懂,它不知道这是文件名还是其他乱码。

修正后的两种脚本方案

方案1:原生Socket实现标准FTP上传

手动处理FTP协议的所有步骤,适合学习底层逻辑:

#!/bin/python3
import socket
import os

def main():
    file_path = input("enter the absolute_file_path of the file you want to upload: ")
    filename = os.path.basename(file_path)  # 只提取文件名,不要完整路径
    filesize = os.path.getsize(file_path)
    
    # 建立控制连接(端口21)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('192.168.190.130', 21))
    print(s.recv(1024).decode('utf-8'))
    
    # 登录服务器
    s.send(b'USER harsh\r\n')
    print(s.recv(1024).decode('utf-8'))
    s.send(b'PASS iacsd@123\r\n')
    print(s.recv(1024).decode('utf-8'))
    
    # 设置二进制传输模式,避免文件损坏
    s.send(b'TYPE I\r\n')
    print(s.recv(1024).decode('utf-8'))
    
    # 用被动模式建立数据连接(大部分FTP服务器默认支持)
    s.send(b'PASV\r\n')
    pasv_response = s.recv(1024).decode('utf-8')
    print(pasv_response)
    
    # 解析被动模式返回的地址和端口
    pasv_parts = pasv_response.split('(')[1].split(')')[0].split(',')
    data_ip = '.'.join(pasv_parts[:4])
    data_port = int(pasv_parts[4]) * 256 + int(pasv_parts[5])
    
    # 建立数据连接
    data_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    data_sock.connect((data_ip, data_port))
    
    # 告诉服务器要上传的文件名
    s.send(f'STOR {filename}\r\n'.encode('utf-8'))
    print(s.recv(1024).decode('utf-8'))
    
    # 传输文件内容
    BUFFER_SIZE = 4096
    with open(file_path, 'rb') as f:
        while True:
            bytes_read = f.read(BUFFER_SIZE)
            if not bytes_read:
                break
            data_sock.sendall(bytes_read)
    
    # 关闭连接收尾
    data_sock.close()
    print(s.recv(1024).decode('utf-8'))
    s.send(b'QUIT\r\n')
    print(s.recv(1024).decode('utf-8'))
    s.close()
    print("File uploaded successfully.")

if __name__ == '__main__':
    main()

方案2:用内置ftplib库(省心又靠谱)

你已经导入了ftplib,直接用它能省掉手动处理协议的繁琐细节:

#!/bin/python3
import ftplib
import os

def main():
    file_path = input("enter the absolute_file_path of the file you want to upload: ")
    filename = os.path.basename(file_path)
    
    try:
        # 连接FTP服务器并登录
        ftp = ftplib.FTP('192.168.190.130')
        ftp.login(user='harsh', passwd='iacsd@123')
        
        # 设置二进制传输模式
        ftp.voidcmd('TYPE I')
        
        # 上传文件
        with open(file_path, 'rb') as f:
            ftp.storbinary(f'STOR {filename}', f)
        
        print("File uploaded successfully.")
        ftp.quit()
    except Exception as e:
        print(f"上传失败:{str(e)}")

if __name__ == '__main__':
    main()

额外检查点

  • 确认vsftpd配置:确保write_enable=YES(允许写入文件)、local_umask=022(保证上传文件权限正常),且用户harsh对自己的FTP主目录(默认是/home/harsh/)有写入权限。
  • 查找文件位置:上传的文件默认保存在harsh的主目录下,直接去/home/harsh/路径查找即可。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 07:02:49