首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LuaSocket FTP总是超时

LuaSocket FTP总是超时
EN

Stack Overflow用户
提问于 2008-10-16 21:25:48
回答 3查看 2.7K关注 0票数 3

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

我想这可能是我需要LuaSocket来使用被动FTP,但后来我发现它似乎默认这样做。我试图通过FTP检索的文件可以通过我机器上的其他程序通过被动FTP访问,但不能通过主动模式访问。我发现some talk对LuaSocket中的被动模式支持进行了“黑客攻击”,这意味着后来的版本停止了使用被动模式,但我的版本似乎还是使用了被动模式(我使用的是2.0.1;最新的是2.0.2,似乎没有任何与我的用例相关的更改)。我对这篇文章如何与我的情况相关感到有点困惑,部分原因是它非常古老,而LuaSocket的源代码现在与讨论中的代码几乎没有相似之处)。

我已经将我的代码归结为:

代码语言:javascript
复制
local ftp = require "socket.ftp"
ftp.TIMEOUT = 10
print(ftp.get("ftp://ftp.us.dell.com/app/dpart.txt"))

这会让我超时。我在Linux上的strace下运行它(与Solaris上的ptrace相同)。以下是简短的文字记录:

代码语言:javascript
复制
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()在结束时成功,然后是这样:

代码语言:javascript
复制
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那样将套接字设置为非阻塞):

代码语言:javascript
复制
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

因此,我在这两个不同的FTP站点上尝试了LuaSocket,虽然失败的原因不同,但却是相似的。我也在另一台运行主动FTP的机器上尝试过,但在那里并没有更好的运气(从我在socket/ftp.lua中阅读源代码可以看出,LuaSocket总是使用被动模式)。

那么,在座的任何人都能让LuaSocket的两行代码在顶层工作吗?请注意,在我的机器上,活动FTP到戴尔的网站不工作(我可以连接,但一旦我做ls它断开),所以如果你让LuaSocket工作,请同时注意活动FTP到戴尔的网站从另一个程序在你的机器上工作。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2008-10-18 02:54:52

嗯。看起来问题是LuaSocket在小写中使用了"pasv“。我要试着想出一个变通的办法。

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

然后编辑本地文件:

代码语言:javascript
复制
-    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时代。)

票数 3
EN

Stack Overflow用户

发布于 2008-11-07 16:38:06

请注意,服务器未能遵循FTP规范,该规范规定命令不区分大小写。见RFC959,第5.3节“命令代码是四个或更少的字母字符。大小写字母字符应被同等对待。因此,以下任何一项都可以表示检索命令: RETR Retr rETr”

票数 1
EN

Stack Overflow用户

发布于 2008-11-07 21:19:06

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

Luasocket对于RFC959是正确的(这里的第一条评论关于大写是不正确的,请参阅RFC959 5.2节)

至少Microsoft FTP服务器不兼容。可能还会有其他人。

解决方案是将pasv更改为PASV,这是区分命令大小写服务器的变通方法。详细信息在Lua电子邮件列表上,几天后就可以在网上访问归档文件。

(编辑ftp.lua的第59行)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/210371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档