python - 在Python中使用ftplib将文件传输到FTP服务器时获取 "Connection refused"

标签 python python-3.x ftp ftplib

我目前正在编写一个 python 脚本来将文本文件上传到 FTP 服务器,但收到以下错误 ConnectionRefusedError: [Errno 61] 连接被拒绝,我一生都做不到。似乎没有弄清楚这个问题。我认为这要么是 FTP 服务器的问题(我可以通过 FileZilla 使用相同的凭据连接到该服务器)。这让我相信这可能是一个编码问题,但经过大量研究,一切看起来都正确完成。所以我决定,违背我更好的判断,跪下来寻求帮助。即使该帮助只是确定问题出在服务器而不是我的代码上。这至少会给我提供下一个排除故障的地方。

预先感谢您提供的任何见解!

这是代码:

import ftplib

def ftp_upload(ftp_obj, path, ftype='TXT'):
    """
    A function for uploading files to an FTP server
    @param ftp_obj: The file transfer protocol object
    @param path: The path to the file to upload
    """
    if ftype == 'TXT':
        with open(path) as fobj:
            ftp.storlines('STOR ' + path, fobj)
    else:
        with open(path, 'rb') as fobj:
            ftp.storbinary('STOR ' + path, fobj, 1024)

if __name__ == '__main__':
    ftp = ftplib.FTP(host='domain or i.p. address')
    ftp.login(user = 'username', passwd = 'password')

    path = input('Please provide path to file: ')
    ftp_upload(ftp, path)

    pdf_path = '/path/to/something.pdf'
    ftp_upload(ftp, pdf_path, ftype='PDF')

    ftp.quit()

这是完整的回溯:

Traceback (most recent call last):
File "ftp_text_file.py", line 21, in <module>
ftp_upload(ftp, path)
File "ftp_text_file.py", line 11, in ftp_upload
ftp.storlines('STOR ' + path, fobj)
File   "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ftplib.py", line 528, in storlines
with self.transfercmd(cmd) as conn:
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ftplib.py", line 397, in transfercmd
return self.ntransfercmd(cmd, rest)[0]
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ftplib.py", line 359, in ntransfercmd
source_address=self.source_address)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 722, in create_connection
raise err
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 713, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 61] Connection refused

更新:提供了 FileZilla 的详细日志,显示我可以连接并上传文件。

Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 0
Status:         Resolving address of my_domain
Status:         Connecting to FTP_server_ip_address:21...
Status:         Connection established, waiting for welcome message...
Trace:          CFtpControlSocket::OnReceive()
Response:   220 (vsFTPd 3.0.3)
Trace:          CFtpLogonOpData::ParseResponse() in state 1
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 5
Command:    USER user 
Trace:          CFtpControlSocket::OnReceive()
Response:   331 Please specify the password.
Trace:          CFtpLogonOpData::ParseResponse() in state 5
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 5
Command:    PASS **********
Trace:          CFtpControlSocket::OnReceive()
Response:   230 Login successful.
Trace:          CFtpLogonOpData::ParseResponse() in state 5
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 6
Command:    SYST
Trace:          CFtpControlSocket::OnReceive()
Response:   215 UNIX Type: L8
Trace:          CFtpLogonOpData::ParseResponse() in state 6
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 7
Command:    FEAT
Trace:          CFtpControlSocket::OnReceive()
Response:   211-Features:
Trace:          CFtpControlSocket::OnReceive()
Response:    UTF8
Response:    EPRT
Response:    EPSV
Response:    MDTM
Response:    PASV
Response:    REST STREAM
Response:    SIZE
Response:    TVFS
Response:   211 End
Trace:          CFtpLogonOpData::ParseResponse() in state 7
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 9
Command:    OPTS UTF8 ON
Trace:          CFtpControlSocket::OnReceive()
Response:   200 Always in UTF8 mode.
Trace:          CFtpLogonOpData::ParseResponse() in state 9
Status:         Logged in
Trace:          Measured latency of 35 ms
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Status:         Retrieving directory listing...
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpListOpData::ListSend() in state 0
Trace:          CFtpChangeDirOpData::Send() in state 0
Trace:          CFtpChangeDirOpData::Send() in state 1
Command:    PWD
Trace:          CFtpControlSocket::OnReceive()
Response:   257 "/home/punc" is the current directory
Trace:          CFtpChangeDirOpData::ParseResponse() in state 1
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Trace:          CControlSocket::ParseSubcommandResult(0)
Trace:          CFtpListOpData::SubcommandResult() in state 1
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpListOpData::ListSend() in state 2
Trace:          CFtpRawTransferOpData::Send() in state 1
Command:    TYPE I
Trace:          CFtpControlSocket::OnReceive()
Response:   200 Switching to Binary mode.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 1
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 2
Command:    PORT 192,168,1,131,195,121
Trace:          CFtpControlSocket::OnReceive()

Response:   200 PORT command successful. Consider using PASV.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 2
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 4
Command:    LIST
Trace:          CTransferSocket::OnAccept(0)
Trace:          CTransferSocket::OnConnect
Trace:          CTransferSocket::TransferEnd(1)
Trace:          CFtpControlSocket::TransferEnd()
Trace:          CFtpControlSocket::OnReceive()
Response:   150 Here comes the directory listing.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 6
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 7
Trace:          CFtpControlSocket::OnReceive()
Response:   226 Directory send OK.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 7
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Trace:          CControlSocket::ParseSubcommandResult(0)
Trace:          CFtpListOpData::SubcommandResult() in state 3
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Status:         Directory listing of "/home/punc" successful
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 0
Status:         Resolving address of my_domain
Status:         Connecting to FTP_server_ip_address:21...
Status:         Connection established, waiting for welcome message...
Trace:          CFtpControlSocket::OnReceive()
Response:   220 (vsFTPd 3.0.3)
Trace:          CFtpLogonOpData::ParseResponse() in state 1
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 5
Command:    USER user 
Trace:          CFtpControlSocket::OnReceive()
Response:   331 Please specify the password.
Trace:          CFtpLogonOpData::ParseResponse() in state 5
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 5
Command:    PASS **********
Trace:          CFtpControlSocket::OnReceive()
Response:   230 Login successful.
Trace:          CFtpLogonOpData::ParseResponse() in state 5
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpLogonOpData::Send() in state 9
Command:    OPTS UTF8 ON
Trace:          CFtpControlSocket::OnReceive()
Response:   200 Always in UTF8 mode.
Trace:          CFtpLogonOpData::ParseResponse() in state 9
Status:         Logged in
Trace:          Measured latency of 50 ms
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Trace:          CFtpControlSocket::FileTransfer()
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpFileTransferOpData::Send() in state 0
Status:         Starting upload of /Users/user/tiny_dancer/Testing/Platinum Pest Control/API_text_results/Eps 256 Platinum Pest-Pest Control Tulsa.txt
Trace:          CFtpChangeDirOpData::Send() in state 0
Trace:          CFtpChangeDirOpData::Send() in state 2
Command:    CWD /home/punc
Trace:          CFtpControlSocket::OnReceive()
Response:   250 Directory successfully changed.
Trace:          CFtpChangeDirOpData::ParseResponse() in state 2
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpChangeDirOpData::Send() in state 3
Command:    PWD
Trace:          CFtpControlSocket::OnReceive()
Response:   257 "/home/punc" is the current directory
Trace:          CFtpChangeDirOpData::ParseResponse() in state 3
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Trace:          CControlSocket::ParseSubcommandResult(0)
Trace:          CFtpFileTransferOpData::SubcommandResult() in state 1
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpFileTransferOpData::Send() in state 5
Trace:          CFtpRawTransferOpData::Send() in state 1
Command:    TYPE A
Trace:          CFtpControlSocket::OnReceive()
Response:   200 Switching to ASCII mode.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 1
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 2
Command:    PORT 192,168,1,131,195,122
Trace:          CFtpControlSocket::OnReceive()
Response:   200 PORT command successful. Consider using PASV.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 2
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 4
Command:    STOR Eps 256 Platinum Pest-Pest Control Tulsa.txt
Trace:          CTransferSocket::OnAccept(0)
Trace:          CTransferSocket::OnConnect
Trace:          CTransferSocket::TransferEnd(1)
Trace:          CFtpControlSocket::TransferEnd()
Trace:          CFtpControlSocket::OnReceive()
Response:   150 Ok to send data.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 6
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 7
Trace:          CFtpControlSocket::OnReceive()
Response:   226 Transfer complete.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 7
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Trace:          CControlSocket::ParseSubcommandResult(0)
Trace:          CFtpFileTransferOpData::SubcommandResult() in state 7
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Status:         File transfer successful, transferred 8,341 bytes in 1 second
Status:         Retrieving directory listing of "/home/punc"...
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpListOpData::ListSend() in state 0
Trace:          CFtpChangeDirOpData::Send() in state 0
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Trace:          CControlSocket::ParseSubcommandResult(0)
Trace:          CFtpListOpData::SubcommandResult() in state 1
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpListOpData::ListSend() in state 2
Trace:          CFtpRawTransferOpData::Send() in state 1
Command:    TYPE I
Trace:          CFtpControlSocket::OnReceive()
Response:   200 Switching to Binary mode.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 1
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 2
Command:    PORT 192,168,1,131,195,123
Trace:          CFtpControlSocket::OnReceive()
Response:   200 PORT command successful. Consider using PASV.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 2
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 4
Command:    LIST
Trace:          CTransferSocket::OnAccept(0)
Trace:          CTransferSocket::OnConnect
Trace:          CTransferSocket::TransferEnd(1)
Trace:          CFtpControlSocket::OnReceive()
Response:   150 Here comes the directory listing.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 4
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpRawTransferOpData::Send() in state 5
Trace:          CFtpControlSocket::TransferEnd()
Trace:          CFtpControlSocket::OnReceive()
Response:   226 Directory send OK.
Trace:          CFtpRawTransferOpData::ParseResponse() in state 7
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Trace:          CControlSocket::ParseSubcommandResult(0)
Trace:          CFtpListOpData::SubcommandResult() in state 3
Trace:          CControlSocket::SendNextCommand()
Trace:          CFtpListOpData::ListSend() in state 4
Status:         Calculating timezone offset of server...
Command:    MDTM Eps 256 Platinum Pest-Pest Control Tulsa.txt
Trace:          CFtpControlSocket::OnReceive()
Response:   213 20180120104523
Trace:          CFtpListOpData::ParseResponse() in state 4
Status:         Timezone offset of server is 0 seconds.
Trace:          CFtpControlSocket::ResetOperation(0)
Trace:          CControlSocket::ResetOperation(0)
Status:         Directory listing of "/home/punc" successful

最佳答案

您的 Python 代码正在使用被动模式。

使用 FileZille,您只能以主动模式进行连接,而不能以被动模式进行连接。

您通常应该使用被动模式。由于它不起作用,您必须修复防火墙/NAT 配置。
看我的文章https://winscp.net/eng/docs/ftp_modes

<小时/>

另一种可能性是 FTP 服务器在 PASV 响应中报告错误的 IP 地址。我们无法判断这一点,因为您混淆了日志中的主 IP 地址。但实际上192.168.1.131是为专用网络保留的IP地址。因此,除非您连接到专用网络内的服务器,否则 IP 地址是错误的。之前链接的文章中也介绍了这一点。

在 vsftpd FTP 服务器中,您可以使用 pasv_address 指令配置外部 IP 地址。
https://security.appspot.com/vsftpd/vsftpd_conf.html

不太理想的解决方案是在本地解决这个问题:
Cannot list FTP directory using ftplib – but FTP client works

<小时/>

当然,您也可以在 Python 脚本中使用主动模式。但这只是一种解决方法,而不是解决方案。

关于python - 在Python中使用ftplib将文件传输到FTP服务器时获取 "Connection refused",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48352480/

相关文章:

python - Python 中的 3D 几何拓扑(例如交叉点)

python - 使用 NTLM 身份验证的 Easy_install 或 pip

python - opencv中读取并显示多张图像

python-3.x - 使用 PySNMP 的 snmpwalk

c - 如何在c中将文本文件中的全文接收到服务器中?

Javascript 和 Python 变量差异

python-3.x - 将 string.capwords 与 Pandas 列一起使用

python - Pyinstaller 3 使用 --onefile 添加数据文件

http - 用于从文件服务器下载文件的协议(protocol)

c# - 使用具有最大值的 FluentFTP 从 FTP 同时下载多个文件