如何使用套接字连接到FTP服务器?

时间:2018-05-01 13:38:31

标签: python-3.x sockets ftp

我正在尝试创建一个简单的FTP客户端,但无论如何都无法建立FTP连接。

我使用了以下代码:

import socket 
sock = socket.socket() 
sock.connect(('localhost', 21)) 
data = 'USER adm\r\n'.encode() 
sock.send(data) 
print('Close') 
sock.close() 

我尝试连接的FTP服务器的日志如下所示:

  

(048507)01.05.2018 06:00:03 - (未登录)(127.0.0.1)>   连接端口21,发送欢迎消息...
  (048507)01.05.2018 06:00:03 - (未登录)(127.0.0.1)>   220-FileZilla Server 0.9.60 beta
      (048507)01.05.2018 06:00:03 - (未登录)(127.0.0.1)> 220 Tim-Kosse撰写(tim.kosse@filezilla-project.org)
      (048507)01.05.2018 06:00:03 - (未登录)(127.0.0.1)> 220请访问https://filezilla-project.org/
      (048507)01.05.2018 06:00:03 - (未登录)(127.0.0.1)>断开。

我尝试发送USER adm命令但在日志中找不到它。如何使用套接字建立与FTP服务器的成功连接?

2 个答案:

答案 0 :(得分:1)

有几个可能的时间问题。

FTP是一个"服务器首先说话"协议。您在日志中看到的220横幅是在接受连接后立即由服务器发送的。客户端应该在发送任何命令之前读取该横幅。 (如果你得到220以外的任何数字代码,服务器就不愿意说话了。)

出于测试目的,我建议您从服务器读取并将您读到的任何内容打印到stdout。您的服务器220横幅是多行FTP响应的示例,其中数字代码后跟第一行的连字符,后跟最后一行的空格。你应该继续阅读,直到你得到一个数字代码后面有空格的行。

如果您不这样做,并且只是在连接完成后立即发送USER,那么您就是在说不通。根据客户端代码运行的速度,服务器可能会在命令之前得到命令,这可以解释为什么它没有响应。

另一个可能的问题是您在发送USER后立即关闭连接,而不等待响应。服务器也可能会注意到这一点。即使它没有尝试检测奇怪的客户端行为,它也可能在尝试发送其响应时出现写入错误,这可以解释为什么它没有正常记录。

伪代码中FTP客户端的整体结构是

connect
read response (banner)
while not done:
    send command
    read response
send QUIT
read response
close

(这省略了真正有趣的部分,即管理数据连接,但你还没有那么远)。

对于您希望获得USER的测试,您至少需要:

connect
read banner
send USER
read response
close

(跳过QUIT可能不会造成任何伤害)

请注意,允许服务器对任何命令(包括USER)返回多行响应,因此您应始终检查数字代码后的空格。编写一个子程序来读取单个FTP响应,并在每个命令后调用它,这是一个好主意。

答案 1 :(得分:0)

执行一次从服务器读取的“第一响应”,以验证它是否“听到”了您的声音,并且在服务器听到您的声音并“回话了”一次之后,进行循环以从服务器读取所有响应,直到服务器安静无响应,就像等待它完成“对话”一样。然后,您可以通过向服务器发送新数据来继续与服务器进行“对话”。

根据其他答案和您的评论答复,您似乎已经从忽略服务器本身何时完成“通话”到在5秒钟的睡眠计时器后期望服务器完成“通话”了,这是不好的。最有效的方法是在再次以客户端身份与服务器“对话”之前,先“聆听”服务器的所有“对话”响应。

这样,您可以在服务器与客户端(客户端)完成“对话”后立即与服务器“对话”。