简体   繁体   English

在 Python 中使用 ftplib 将文件传输到 FTP 服务器时出现“连接被拒绝”

[英]Getting "Connection refused" when transferring a file to FTP server with ftplib in Python

I am currently working on a python script to upload text files to an FTP server but am getting the following error ConnectionRefusedError: [Errno 61] Connection refused , and for the life of me I can't seem to figure out the issue.我目前正在使用 python 脚本将文本文件上传到 FTP 服务器,但出现以下错误ConnectionRefusedError: [Errno 61] Connection refused ,对于我来说,我似乎无法弄清楚这个问题。 I believe it is either an issue with the FTP server (which I can connect to with the same credentials via FileZilla).我相信这要么是 FTP 服务器的问题(我可以通过 FileZilla 使用相同的凭据连接到它)。 Which led me to believe it could be a coding issue, but after much research, everything looks to be done correctly.这让我相信这可能是一个编码问题,但经过大量研究,一切看起来都是正确的。 So I decided, against my better judgement, to come here on my knees asking for some help.所以我决定,违背我更好的判断,跪下来寻求帮助。 Even if that help is only determining that the issue is with the server and not my code.即使该帮助只是确定问题出在服务器上而不是我的代码上。 That will at least give me the next place to troubleshoot.这至少会给我下一个故障排除的地方。

Thank you in advance for any insight you can provide!预先感谢您提供的任何见解!

Here is the code:这是代码:

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()

Here is the complete traceback:这是完整的回溯:

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

Update: Provided the verbose logs from FileZilla showing I can connect and upload a file.更新:提供了 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

Your Python code is using passive mode.您的 Python 代码正在使用被动模式。

With FileZille you can connect only in an active mode, but not in passive.使用 FileZille,您只能以主动模式连接,而不能以被动模式连接。

You generally should use the passive mode.您通常应该使用被动模式。 As it does not work, you have to fix firewall/NAT configuration.由于它不起作用,您必须修复防火墙/NAT 配置。
See my article https://winscp.net/eng/docs/ftp_modes看我的文章https://winscp.net/eng/docs/ftp_modes


Another possibility is that the FTP server reports wrong IP address in the PASV response.另一种可能是 FTP 服务器在PASV响应中报告了错误的 IP 地址。 We cannot tell that as you have obfuscated a primary IP address in the log.我们无法确定这一点,因为您混淆了日志中的主要 IP 地址。 But indeed 192.168.1.131 is IP address reserved for private.networks.但实际上 192.168.1.131 是为 private.networks 保留的 IP 地址。 So unless you are connecting to the server within a private.network, the IP address is wrong.因此,除非您连接到 private.network 中的服务器,否则 IP 地址是错误的。 This is also covered on the previously linked article.这也在之前链接的文章中有所介绍。

In vsftpd FTP server, you configure an external IP address using pasv_address directive.在 vsftpd FTP 服务器中,您使用pasv_address指令配置外部 IP 地址。
https://security.appspot.com/vsftpd/vsftpd_conf.html https://security.appspot.com/vsftpd/vsftpd_conf.html

Less optimal solution is working this around on the local side:不太理想的解决方案是在本地解决这个问题:
Cannot list FTP directory using ftplib – but FTP client works无法使用 ftplib 列出 FTP 目录 – 但 FTP 客户端工作


Or you can, of course, use the active mode in your Python script.当然,您也可以在 Python 脚本中使用活动模式。 But that's rather a workaround than a solution.但这是一种解决方法,而不是解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM