2008-10-16 58 views
3

我已经成功使用了LuaSocket的TCP设备,但是我的FTP模块出现问题。试图检索(小)文件时,我总是会遇到超时。我可以在被动模式下使用Firefox或ftp(在Ubuntu Dapper Linux上)下载文件。LuaSocket FTP总是超时

我认为这可能是我需要LuaSocket来使用被动FTP,但后来我发现它似乎默认做到这一点。我试图通过FTP检索的文件可以通过被动FTP通过我的机器上的其他程序访问,但不能通过主动模式访问。我发现some talk关于将“被动模式”支持“入侵”到LuaSocket中,这个讨论意味着后来的版本停止使用被动模式,但是我的版本似乎仍然使用被动模式(我使用2.0.1;最新版本是2.0.2,而不是似乎有任何与我的用例相关的更改)。我对这篇文章与我的情况之间的关系有些困惑,部分原因是因为它非常陈旧,现在LuaSocket的源代码与该讨论中的代码几乎没有相似之处)。

我煮我的代码到这一点:

local ftp = require "socket.ftp" 
ftp.TIMEOUT = 10 
print(ftp.get("ftp://ftp.us.dell.com/app/dpart.txt")) 

这给了我超时。我在Linux上运行它strace(与Solaris上的ptrace相同)。下面是一个简化的成绩单:

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 
fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 
recv(3, "230-Welcome to the Dell FTP site."..., 8192, 0) = 971 
send(3, "pasv\r\n", 6, 0)    = 6 
recv(3, 0x8089a58, 8192, 0)    = -1 EAGAIN (Resource temporarily unavailable) 
select(4, [3], NULL, NULL, {9, 999934}) = 0 (Timeout) 

有我尝试连接到其他网站,但它有它,我不能在这里发表一个密码,但在这种情况下的结果略有不同...我得到跟踪,如但其具有select()末成功,那么这样的:

recv(3, "227 Entering Passive Mode (123,456,789,0,12,34)\r\n", 8192, 0) = 49 
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4 
fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0 
connect(4, {sa_family=AF_INET, sin_port=htons(12345), sin_addr=inet_addr("123.456.789.0")}, 16) = -1 EINPROGRESS (Operation now in progress) 
select(5, [4], [4], NULL, {9, 999694}) = 0 (Timeout) 

与此相比,在被动模式下(工作正常我的“FTP”程序的痕迹,但要注意,它并没有设置套接字非阻塞像LuaSocket):

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 6 
write(5, "PASV\r\n", 6)     = 6 
read(3, "227 Entering Passive Mode (123,456,789,0,12,34)\r\n", 1024) = 51 
connect(6, {sa_family=AF_INET, sin_port=htons(12345), sin_addr=inet_addr("123.456.789.0")}, 16) = 0 

所以我已经尝试过使用LuaSocket针对这两个不同但类似的失败的FTP站点。我也从另一台主动FTP工作的机器上尝试过,并且它没有更好的运气(大概是因为LuaSocket总是使用被动模式,通过阅读socket/ftp.lua中的源文件可以知道)。

因此,任何人都可以在这里制作LuaSocket双引擎作品吗?请注意,在我的计算机上,活动的FTP到戴尔的网站不起作用(我可以连接,但只要我做了ls它就会断开连接),所以如果您使LuaSocket正常工作,还请注意是否从其他程序启动了到戴尔网站的FTP活动在你的机器上。

回答

3

嗯。看起来问题是LuaSocket使用小写的“pasv”。我会试着找出解决方法。


嗯。不,它看起来非常优雅地焊接。最简单的做法可能是将那个特定的文件复制到LUA_PATH中早期路径的层次结构中的对应位置。即(通常)制作文件的本地副本,例如path/to/your/project/socket/ftp.lua

然后编辑本地文件:

- self.try(self.tp:command("user", user or USER)) 
+ self.try(self.tp:command("USER", user or USER)) 
-  self.try(self.tp:command("pass", password or PASSWORD)) 
+  self.try(self.tp:command("PASS", password or PASSWORD)) 
- self.try(self.tp:command("pasv")) 
+ self.try(self.tp:command("PASV")) 
- self.try(self.tp:command("port", arg)) 
+ self.try(self.tp:command("PORT", arg)) 
- local command = sendt.command or "stor" 
+ local command = sendt.command or "STOR" 
- self.try(self.tp:command("cwd", dir)) 
+ self.try(self.tp:command("CWD", dir)) 
- self.try(self.tp:command("type", type)) 
+ self.try(self.tp:command("TYPE", type)) 
- self.try(self.tp:command("quit")) 
+ self.try(self.tp:command("QUIT")) 

事与愿违,使用getfenv,getmetatable等一navelnaut探险队似乎并不值得。我认为这是设计中的一个严重问题。(LuaSocket)

值得注意的是,RFC0959使用全部大写命令。 (可能是因为它来自7位ASCII时代。)

+0

这完全有效。除了你的清单之外,我还将“retr”改为“RETR”,但就是这样。做得好。 – 2008-10-20 16:41:44

1

请注意,服务器未能遵循FTP规范,其中状态命令不区分大小写。请参阅RFC959的第5.3节“命令代码是四个或更少的字母字符 大写和小写字母字符将被同等对待 因此,以下任一可能代表 检索命令:RETR Retr retr ReTr rETr”

1

现在解决了这个问题,问题和第一个答案很有帮助。

Luasocket是正确的RFC 959(第一在这里评论是不正确的约大写,见RFC959第5.2节)

至少微软的FTP服务器不兼容。可能还有其他人。

解决方案将pasv更改为PASV,并且是解决命令区分大小写的服务器的解决方法。详细信息在Lua电子邮件列表中,其中存档将在几天内在网络上访问。

(编辑ftp.lua第59行)