我必须在C中为linux编写一个小命令行FTP客户端。它适用于常见用途(目录管理,检索和存储文件等),我想添加活动模式(目前每次转移都是在被动模式下进行的。) 我知道我必须发送以下形状的命令:
PORT a,b,c,d,e,f
其中a b c d
是IP地址块,e f
是端口号。但是,据我所知,ip必须是我的客户端运行的机器的IP,但我被建议使用getsockname()
。根据我的测试,getsockname()
获取我的套接字使用的接口的本地IP,而不是我从互联网上看到的ip。所以我不能给这个服务器连接的IP地址。
问题是:我是否正确理解了命令PORT
,以及如何获取正确的ip来发送它?
答案 0 :(得分:1)
FTP活动模式意味着服务器打开与客户端的连接并自行发送数据。这通常是不切实际的,因此发明了被动模式:服务器打开一个额外的端口,监听传入的连接,并在有人连接时开始传输。
因此,被动模式会话如下所示:
$ 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.
虽然是活动会话的一个例子:
$ 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.
P.S。 FTP是一个非常古老的协议(定义从大约1970年),定义时没有路由器,门和其他传输级别的好东西,通常有几台机器,直接连接,所以主动模式工作得很好,被动模式是如何协议今天幸存下来。
所以,是的,你已经获得了PORT命令,但是没有统一的方法来获取你的外部IP(在本地机器上的几个不同的网络中可能有几个你的IP,可能有几个门在他们自己的网络上到服务器的方式,你想用哪一个?)。问题的第二部分,如何获取服务器看到的IP,无法回答(这就是被动模式的用途)。
答案 1 :(得分:0)
如果你是NAT的背后,NAT的责任是打破端到端原则^ W ^ W ^ W ^ WNAT PORT / 226命令/响应中的地址。 NAT应该明确支持FTP。