c - 如何在C、linux中为FTP客户端启动主动模式

标签 c linux networking ftp ip

我必须在 C 中为 linux 编写一个小的命令行 FTP 客户端。它在常见用途(目录管理、检索和存储文件等)方面工作得很好,我想添加事件模式(目前每次传输都是在被动模式下进行的)。
我知道我必须以以下形式发送命令:

PORT a,b,c,d,e,f

a b c d 是 ip 地址 block ,e f 是端口号。但是,据我所知,该 ip 必须是运行我的客户端的机器的 ip,但有人建议我使用 getsockname()。根据我的测试,getsockname() 获取我的套接字使用的接口(interface)的本地 ip,而不是我从互联网上看到的 ip。所以我不能给服务器连接这个IP地址。

问题是:我是否正确理解命令 PORT,以及如何获得正确的 ip 来发送它?

最佳答案

FTP 主动模式意味着服务器打开到客户端的连接并自行发送数据。这通常是不切实际的,因此发明了被动模式:服务器打开一个额外的端口来监听传入的连接并在有人连接时开始传输。

因此,被动模式 session 如下所示:

$ telnet localhost 21
220 Welcome to EarlGray FTP
USER ftp
331 Please specify the password.
PASS ftp
230 Login successful.
PASV 
227 Entering Passive Mode (127,0,0,1,185,37).
LIST
150 Here comes the directory listing.
            ---> here client opens another telnet session, 
            ---> connecting to the same server on port 185*256+37, specified by server:
              $ telnet localhost $((185 * 256 + 37))
              Trying 127.0.0.1...
              Connected to localhost.
              Escape character is '^]'.
              drwxrwxr-x    2 121      1003         4096 Aug 21 10:57 incoming
              drwxrwxr-x    7 0        1003         4096 Nov 09 21:04 pub
              Connection closed by foreign host.
            <---- end of data transfer session

226 Directory send OK.

而事件 session 的示例:

$ telnet localhost 21
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 Welcome to EarlGray FTP
USER ftp
331 Please specify the password.
PASS ftp
230 Login successful.
PORT 127,0,0,1,45,45                      (ports are specified by client)
200 PORT command successful. Consider using PASV.
LIST
150 Here comes the directory listing.

        ---> here client listens for an incoming connection on port 45*256+45
          $ nc -l 0.0.0.0 $((45 * 256 + 45))
          drwxrwxr-x    2 121      1003         4096 Aug 21 10:57 incoming
          drwxrwxr-x    7 0        1003         4096 Nov 09 21:04 pub
        <--- data are rececived

226 Directory send OK.

附言FTP 是一个非常古老的协议(protocol)(大约 1970 年的定义),在没有路由器、网关和其他传输层好东西的时候定义,通常有几台机器直接连接,所以主动模式工作得很好,被动模式是如何协议(protocol)在今天仍然存在。

所以,是的,你已经正确地获得了 PORT 命令,但是没有统一的方法来获取你的外部 IP(本地机器上的几个不同网络中可能有几个你的 IP,可能有几个 gates 有自己的网络服务器的方式,你想使用哪一种?)。问题的第二部分,如何获取服务器看到的 IP,无法回答(这就是被动模式的目的)。

关于c - 如何在C、linux中为FTP客户端启动主动模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13479499/

相关文章:

c - 如何在 dbx 中打印长字符串的完整值?

计算数组元素的百分比

c - g_hash_table_destroy() 调用时,是否释放缓冲区内存

java - Java 和 C/C++ 程序之间的命名管道

java - java中使用socket编程的聊天程序

c - 执行两个或多个相同类型的线程时出现问题 - Pthread C

c++ - 什么 (*(void(*)()) shellcode)();方法?

c++ - 为 ARM 交叉编译 ncurses 5.9 - 找不到表单库

linux - 如果临时文件存在于 Ubuntu 操作系统中,如何清理(删除)它们?

linux - RSS、RPS 和 RFS 之间的主要区别是什么?