在Python中从客户端发送不同文件到服务器

1 投票
2 回答
870 浏览
提问于 2025-04-18 03:34

我正在尝试在Python中从客户端发送文件到服务器。文件确实发送成功了,但问题是我收到的文件名和原来的不一样。比如说,文件名是File1.txt,但我在服务器上收到的却是file_.txt。我写的代码如下:

客户端代码

import socket, os, shutil
from stat import ST_SIZE
HOST=raw_input("Please enter IP-address :  ")

PORT=int(raw_input("Please enter PORT Number : "))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
if s.recv(8)!='READY':
    raw_input('Unable to connect \n\n Press any key to exit ...')
    s.close()
    exit()
path=raw_input("Please enter the complete PATH of your file :  ")

f=open(path,'rb')
fsize=os.stat(f.name)[ST_SIZE]


s.sendall(str(fsize).zfill(8))
sfile = s.makefile("wb")
shutil.copyfileobj(f, sfile)
sfile.close()
s.close()
f.close()

服务器代码

import socket
import shutil
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = ''
PORT = 31400
s.bind((HOST, PORT))
s.listen(3)
conn, addr = s.accept()               
print 'conn at address',addr
conn.sendall('READY')
i=1
f = open(r'file_'+ str(i)+".txt",'wb')
i=i+1
fsize=int(conn.recv(8))               
print 'File size',fsize
sfile = conn.makefile("rb")
shutil.copyfileobj(sfile, f)
sfile.close()

f.write(conn.recv(fsize))             
f.close()
conn.close()
s.close()

我该如何才能保持文件名不变呢?如果我需要接收其他类型的文件,比如.pdf、.txt、.jpeg等,又该怎么做?请帮帮我,我对Python还很陌生。

2 个回答

1

你要么使用一个库,比如ftputil,要么就得用某种方式对文件进行编码,比如UUENCODE

另外,你也可以自己实现一个协议,分开处理文件名和大小,然后再发送文件内容。具体步骤如下:

  • 客户端获取文件路径,然后检查文件大小,并分离出文件的基本名称。
  • 客户端以预先格式化的方式发送文件的基本名称和大小。
  • 服务器接收并解析这些信息,然后打开一个名为基本名称的文件以进行写入。
  • 客户端发送二进制数据。
  • 服务器将二进制数据写入打开的文件。
  • 双方计算文件的MD5值(或类似的校验和),并交换信息以确保它们匹配。

请注意,上述内容没有涵盖处理一些问题,比如数据丢失、仅支持ASCII的链接、文件损坏、分块发送等。要知道,FTP自1971年以来一直在积极使用和开发,直到1998年才提出了一些根本性的变化建议。

1

首先,你在服务器上并没有直接收到一个叫做 file_.txt 的文件,而是新建了一个文件,命名为 file_.txt,然后把你收到的内容复制到这个新创建的 file_.txt 文件里。

我的解决办法是从文件中获取文件名,并把它和内容一起发送过去。获取文件名的例子如下:

import os
print os.path.splitext("path_to_file")[0]

撰写回答