使用 socket.py 向 FTP 服务器发出列表请求并获取文件列表

Using socket.py to make a List request towards the FTP server and get file list

我需要向特定 FTP 服务器发出请求并发出 LIST/NLST 请求以获取所有文件的列表(我想至少从当前目录开始)而不使用库像 ftplib,只使用 socket.py。这是我的看法(ip,用户名和密码实际上已填写,如果可能我不想分享它们):

    port = 21
    ip = ""
    buff_size = 1024
    username = ""
    password = ""
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((ip, port))
    print(s.recv(buff_size).decode())
    s.send("USER {}\r\n".format(username).encode())
    print(s.recv(buff_size).decode())
    s.send("PASS {}\r\n".format(password).encode())
    print(s.recv(buff_size).decode())
    s.send("PASV\r\n".encode())
    print(s.recv(buff_size).decode())
    s.send("LIST\r\n".encode())
    print(s.recv(buff_size).decode())
    s.send("QUIT\r\n".encode())
    print(s.recv(buff_size).decode())

控制台的响应是:

220 (vsFTPd 3.0.2)
331 Please specify the password.
230 Login successful.
227 Entering Passive Mode (xx,xxx,xxx,xx,138,136).
425 Failed to establish connection.
221 Goodbye

在 227 和 425 代码之前大约需要 1 分钟的时间,直到它进行到 425。 我尝试了很多不同的东西(我也尝试了主动模式而不是被动模式,但我不明白我如何获得端口,我试图暴力破解它并从中获取所有可能的端口组合两个字节(变量 a 和 b)都为 0 到 255,但无济于事)

s.send("PORT {}\r\n".format("xx,xxx,xxx,xx,"+str(a)+","+str(b)).encode())

但我对可能是什么原因一无所知。不知道是network/settings的原因还是代码的原因。 Ftplibs 似乎正确地完成了工作(我首先使用 ftplib 编写了一个应用程序只是为了测试给定的服务器),所以我认为这是代码,也许是关于安全的(就像我是从控制台应用程序而不是浏览器做的) ,我应该将请求作为一个发送,但我对它是如何完成的一无所知) 以防万一我尝试切换到没有路由器的不同(移动)网络并且结果是相同的(这与我的 ISP 或路由器无关)。防火墙也为此关闭了。系统是Windows10,我用的是PyCharm

我明白了,LIST 响应有效。我正在向端口 20 发送请求并从 21 读取响应。我需要发送到 21 并从 20 读取。 现在代码如下所示:

port = 21
ip = ""
buff_size = 1024
username = ""
password = ""

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
print(s.recv(buff_size).decode())

s.send("USER {}\r\n".format(username).encode())
print(s.recv(buff_size).decode())

s.send("PASS {}\r\n".format(password).encode())
print(s.recv(buff_size).decode())

s.send("PASV\r\n".encode())
str = s.recv(buff_size).decode()
print(str)
str = str.split(',')
lport = str[-1].replace(').\r\n','')
hport = str[-2]
newport = int(hport)*256+int(lport)

s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.connect((ip, newport))

def message_data_send(command):
    s1.send(("{}".format(command)+"\r\n").encode())
    print(s.recv(buff_size).decode())

def message_command_send(command):
    s.send(("{}".format(command)+"\r\n").encode())
    print(s.recv(buff_size).decode())
    if command=='NLST':
        print(s.recv(buff_size).decode())
        print(s1.recv(buff_size).decode())
    if command=='LIST':
        s.recv(buff_size).decode()
        print(s1.recv(buff_size).decode())
message_command_send('LIST')