我在使用一段非常简单的代码片段时遇到了一些麻烦:
private long getFTPLogLength()
{
long size;
FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURL));
ftpRequest.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
try
{
ftpRequest.ReadWriteTimeout = 6000;
ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
FtpWebResponse respSize = (FtpWebResponse)ftpRequest.GetResponse();
size = respSize.ContentLength;
respSize.Close();
}
catch (Exception ex)
{
logLog.writeEntry(4, "Error getting logsize from FTP: " + ex.Message);
size = 0;
}
return size;
}
这种方法的重点是显然获取特定文件的长度。这里的问题是在某些服务器(即gameservers.com服务器)上,此代码不起作用。它适用于我可以测试的每种其他服务器类型。
我在寻找一些帮助时找到了这个:C# FTP 550 error我尝试了一个斜杠和两个,我仍然得到相同的结果。为了更进一步,当我执行GetFileSize(SIZE)时,我只得到550错误。如果我执行GetDateTime(MDTM),它不会抛出此错误。这会让您相信SIZE命令已被禁用,或者我无权使用它,但是如果我使用FileZilla(或任何客户端)连接到服务器,并运行SIZE games_mp.log工作得很好。
这是异常后调试器的屏幕截图(注意,我为了修复这个bug而购买了这个游戏服务器,所以凭据有意为您的测试乐趣留下了凭据)。
任何可以帮助我弄清楚我需要做些什么才能使其与服务器一起工作的信息会有所帮助。希望我遗漏一些简单的东西。 :)
经过一些更多的测试,如果我让FileZilla超时,他们我手动运行命令,我得到一个错误,关于SIZE不支持ASCII模式,但如果我开始一个新的连接到服务器它工作正常。
与服务器的新连接:
超时后的命令:
希望这对某人意味着什么......
答案 0 :(得分:4)
(注意:我在这里编写了FTP服务器软件并且可以访问发生了什么的原始服务器日志)
这里的问题相当简单,当您在Filezilla中尝试SIZE命令时,您处于二进制传输模式。当您尝试通过客户端运行此命令时(或在重新连接Filezilla之后),您处于ASCII传输模式。
查看实际的访问日志,似乎在初始连接上,Filezilla执行“#I; TYPE I'其次是MLSD'。当它之后重新连接时,它不会再次尝试MLSD命令,因此它不会打扰执行“类型I”。
在ASCII模式下计算实际文件大小是相当耗费资源的(特别是考虑到您的代码本质上会非常频繁地尝试此命令)。它要求我们解析整个文件并替换所有行结束字符。这不是我们想要在繁忙的FTP服务器上一直做的事情。
这种行为实际上由RFC来解释:
对SIZE存在550错误响应 命令不得被客户端视为指示 文件无法在当前MODE和TYPE中传输。一台服务器 可能由于其他原因而产生此错误 - 例如,如果 处理开销被认为太大了。
在ASCII模式下:
ncftp / > quote size games_mp.log
> quote size games_mp.log
Cmd: size games_mp.log
550: SIZE not allowed in ASCII mode.
SIZE not allowed in ASCII mode.
在BINARY模式中:
ncftp / > quote size games_mp.log
> quote size games_mp.log
Cmd: size games_mp.log
213: 134901
134901
因此,您在此处的实际修复是在尝试获取文件大小之前切换到二进制模式。
我们也非常希望您更改帐户的密码。我们过去曾看到过开放FTP帐户的重大滥用行为(有些人认为需要填写他们发现的各种盗版内容的FTP帐户。)
答案 1 :(得分:2)
Ftp SIZE命令在基本FTP RFC中不存在,仅在RFC 3659中添加。 而且,FTP的错误550是“动作不可用”,即服务器告诉它它不支持这样的命令。
答案 2 :(得分:1)
如果服务器支持FEAT命令,则将其发送到服务器,并查看结果列表中是否包含“SIZE”。这应该告诉您服务器是否支持SIZE命令。这个假设服务器支持FEAT命令本身。