【问题标题】:Using FTP commands to download a file with sockets使用 FTP 命令下载带有套接字的文件
【发布时间】:2020-02-05 20:15:03
【问题描述】:

我使用的是专有编程语言,它没有内置的FTP 函数。因此我使用sockets

sHandle := SocketOpen('ftp.stackoverflow.net', 21);
SocketReadString(sHandle, answer);

retW := SocketWriteString(sHandle, 'user user1673665' & CHR(13) & CHR(10));
SocketReadString(sHandle, answer);
retW := SocketWriteString(sHandle, 'pass !@#$%^&*' & CHR(13) & CHR(10));
SocketReadString(sHandle, answer);

retW := SocketWriteString(sHandle, 'cwd update' & CHR(13) & CHR(10));
SocketReadString(sHandle, answer);
retW := SocketWriteString(sHandle, 'retr update.txt' & CHR(13) & CHR(10));
SocketReadString(sHandle, answer);

SocketClose(sHandle);

这些是我从FTP 服务器收到的答案:

220-欢迎使用 stackoverflow FTP
220 未经授权的访问是非法的!
user1673665需要331密码
230 已登录
250 CWD 成功。 “/update”是当前目录。

但是为什么我在retr update.txt之后会得到这个错误:

503 错误的命令序列。

我正在逐步调试代码。因此响应时间应该不是问题。

【问题讨论】:

    标签: sockets download ftp command downloadfile


    【解决方案1】:

    RETR 命令之前必须至少有 PASVPORT 以设置数据连接。

    咨询RFC 959,特别是“3.2.建立数据连接”部分

    使用PASV 时,您必须打开服务器在227 响应中返回的端口的连接。


    另外请注意,FTP 命令必须以大写形式发送。

    【讨论】:

    • 感谢 Martin Prikryl 的帮助。我已经添加了完整的工作代码,也许对某人有用。
    【解决方案2】:

    感谢 Martin Prikryl 和 Steffen Ullrich 的帮助。我将在此处使用 cmets 添加工作代码。也许它对某人有用。也许有必要添加睡眠命令,因为代码运行速度比服务器响应快。

    # Open control channel
    sHandle := SocketOpen('ftp.stackoverflow.net', 21);
    SocketReadString(sHandle, answer);
    SocketWriteString(sHandle, 'USER user1673665' & CHR(13) & CHR(10));
    SocketReadString(sHandle, answer);
    SocketWriteString(sHandle, 'PASS !@#$%^&*' & CHR(13) & CHR(10));
    SocketReadString(sHandle, answer);
    SocketWriteString(sHandle, 'CWD update' & CHR(13) & CHR(10));
    SocketReadString(sHandle, answer);
    # Enter passive mode and receive data channel adress and port
    SocketWriteString(sHandle, 'PASV' & CHR(13) & CHR(10));
    SocketReadString(sHandle, answer);
    # Create adress for data channel
    IF answer <> NOVALUE THEN
      # Split answer on character , and ( and ) and whitespace
      retPASV[] := StrSplit(answer, ',() ');
    ENDIF;
    CASE retPASV[1]
        # Passive mode is 227
      IS = 227 DO
        connect := retPASV[6] & '.' & retPASV[7] & '.' & retPASV[8] & '.' & retPASV[9];
      IS DO
    ENDCASE;
    # Create port for data channel
    # Port is secondlast number * 256 + last number from PASV reply
    port := String2Num(retPASV[10]) * 256 + String2Num(retPASV[11]);
    # Open data channel on sHandle2
    sHandle2 := SocketOpen(connect, port);
    SocketReadString(sHandle2, answer2);
    # Download file on control channel
    SocketWriteString(sHandle, 'RETR update.txt' & CHR(13) & CHR(10));
    SocketReadString(sHandle, Antwort);
    # Read file on data channel - result of textfile in string answer2
    SocketReadString(sHandle2, answer2);
    SocketClose(sHandle);
    

    【讨论】:

      【解决方案3】:

      为什么retr update.txt 不起作用?

      因为您没有遵循 FTP 协议的规范。数据传输使用单独的 TCP 连接完成,需要使用 PASVEPSVPORTEPRT 命令预先设置。有关更多信息,请参阅标准(这就是它们的用途),即 RFC 959RFC 2428

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-09
        • 1970-01-01
        • 2017-04-14
        • 2015-06-05
        相关资源
        最近更新 更多