代码之家  ›  专栏  ›  技术社区  ›  RossFabricant

C禁用CD的FTP

  •  6
  • RossFabricant  · 技术社区  · 16 年前

    我正在尝试使以下代码正常工作:

      string url = String.Format(@"SOMEURL");
      string user = "SOMEUSER";
      string password = "SOMEPASSWORD";
    
      FtpWebRequest ftpclientRequest = (FtpWebRequest)WebRequest.Create(new Uri(url));
      ftpclientRequest.Method = WebRequestMethods.Ftp.ListDirectory;
      ftpclientRequest.UsePassive = true; 
      ftpclientRequest.Proxy = null;
      ftpclientRequest.Credentials = new NetworkCredential(user, password);
      FtpWebResponse response = ftpclientRequest.GetResponse() as FtpWebResponse;
    

    这通常有效,但对于1个特定的服务器,这会产生错误500:语法无法识别。问题服务器上禁用了change directory命令,站点管理员告诉我.NET默认情况下会对所有ftp连接发出change directory命令。是真的吗?有没有办法让它失效?
    编辑:当我从命令行登录时,我在正确的目录中:
    光纤光栅
    257“/”是当前目录

    5 回复  |  直到 7 年前
        1
  •  11
  •   erlando    13 年前

    我刚在我们的一个dev服务器上测试过这个,实际上有一个由.NET ftpwebRequest发布的CWD:

    new connection from 172.16.3.210 on 172.16.3.210:21 (Explicit SSL)
    hostname resolved : devpc
    sending welcome message.
    220 Gene6 FTP Server v3.10.0 (Build 2) ready...
    USER testuser
    testuser, 331 Password required for testuser.
    testuser, PASS ****
    testuser, logged in as "testuser".
    testuser, 230 User testuser logged in.
    testuser, OPTS utf8 on
    testuser, 501 Please CLNT first.
    testuser, PWD
    testuser, 257 "/" is current directory.
    testuser, CWD /
    testuser, change directory '/' -> 'D:\testfolder' --> Access allowed.
    testuser, 250 CWD command successful. "/" is current directory.
    testuser, TYPE I
    testuser, 200 Type set to I.
    testuser, PORT 172,16,3,210,4,127
    testuser, 200 Port command successful.
    testuser, NLST
    testuser, 150 Opening data connection for directory list.
    testuser, 226 Transfer ok.
    testuser, 421 Connection closed, timed out.
    testuser, disconnected. (00d00:05:01)
    

    创建ftpWebRequest对象时,甚至没有在URI中指定“/”。

    如果调试或浏览源代码,则会使用一个名为“ftpcontrolstream”的类。参见调用堆栈:

    System.dll!System.Net.FtpControlStream.BuildCommandsList(System.Net.WebRequest req) Line 555    C#
    System.dll!System.Net.CommandStream.SubmitRequest(System.Net.WebRequest request = 
        {System.Net.FtpWebRequest}, bool async = false, bool readInitalResponseOnConnect = true) Line 143   C#
    System.dll!System.Net.FtpWebRequest.TimedSubmitRequestHelper(bool async) Line 1122 + 0x13 bytes C#
    System.dll!System.Net.FtpWebRequest.SubmitRequest(bool async = false) Line 1042 + 0xc bytes C#
    System.dll!System.Net.FtpWebRequest.GetResponse() Line 649  C#
    

    有一个名为buildcommandslist()的方法被调用。buildcommandslist()生成要发送到ftp服务器的命令列表。此方法包含以下代码片段:

    if (m_PreviousServerPath != newServerPath) { 
        if (!m_IsRootPath
            && m_LoginState == FtpLoginState.LoggedIn
            && m_LoginDirectory != null)
        { 
            newServerPath = m_LoginDirectory+newServerPath;
        } 
        m_NewServerPath = newServerPath; 
    
        commandList.Add(new PipelineEntry(FormatFtpCommand("CWD", newServerPath), PipelineEntryFlags.UserCommand)); 
    }
    

    当第一次连接到服务器m_PreviousServerPath时,newServerPath的值为“/”,并由名为getPathAndFileName()的函数计算(在该代码块之前调用了几行)。getPathAndFileName()如果未提供路径或如果在'ftp:/…'uri'的末尾显式附加了“/”,则将newServerPath计算为“/”。

    因此,这当然最终会导致将cwd命令添加到命令管道中,因为该命令为空!=“/”。

    简而言之,不幸的是,您不能覆盖这个行为,因为它在源代码中被烧掉了。

        2
  •  1
  •   eeerahul Arrj    13 年前

    虽然这篇文章就像很久以前一样…没关系,我会在这里提供答案。

    而不是使用 ftp://server/path 作为URI,尝试 ftp://server/%2fpath/ .

    增加的 %2f “只是个逃犯 / ,添加此选项将使C将整个路径视为绝对路径。 否则C将登录到 ftp://server/ 使用用户名,转到用户的主文件夹,然后cd到指定的路径,这样您的路径就变成 user_home_path/path 可能不可取。

    可以在msdn上找到更多信息 http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx

    希望这有帮助。

        3
  •  0
  •   Sijin    16 年前

    我想我们以前也有类似的问题,但我不记得具体细节。

    要防止.NET发出cd命令,请查看是否将要登录的用户的默认目录设置为要在其中工作的目录。您只需使用命令行ftp客户机来检查它。

        4
  •  0
  •   David Grayson    16 年前

    这里有一个解决方案:使用这个由dan在c-sharpcorner.com制作的免费的开源ftp客户端库: http://www.c-sharpcorner.com/uploadfile/danglass/ftpclient12062005053849am/ftpclient.aspx

    以下是上载文件的示例代码:

    FtpClient ftp = new FtpClient(FtpServer,FtpUserName,FtpPassword);
    ftp.Login();
    ftp.Upload(@"C:\image.jpg");
    ftp.Close(); 
    

    这个库可以在开箱即用的情况下正常工作,但也可以很容易地扩展和修改。

        5
  •  0
  •   Jim Software    7 年前

    利用上面的信息,这对我很有效。

    发送CWD ftpstate.ftprequest=获取请求(“ ftp://192.168.0.2/tmp/file2download “”

    不发送CWD- ftpstate.ftprequest=获取请求(“ ftp://192.168.0.2//tmp/file2download “” 注意服务器IP(或名称)后面的//

    dotnet版本2.0

    Private Function GetRequest(ByVal URI As String) As FtpWebRequest
        'create request
        Dim result As FtpWebRequest = CType(FtpWebRequest.Create(URI), FtpWebRequest)
        Return result
    End Function