문제

다음 코드가 작동하려고합니다.

  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 : 구문이 인식되지 않습니다. 문제 서버에서 변경 디렉토리 명령이 비활성화되어 있으며 사이트 관리자는 .NET이 모든 FTP 연결과 함께 기본적으로 변경 디렉토리 명령을 발행한다고 말했습니다. 그게 사실인가요? 그것을 비활성화하는 방법이 있습니까?
편집 : 명령 줄에서 로그인하면 올바른 디렉토리에 있습니다.
ftp> pwd
257 "/"는 현재 디렉토리입니다

도움이 되었습니까?

해결책

방금 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 "/"는 현재 디렉토리입니다. testuser, cwd / testuser, 변경 디렉토리 ' /' -> 'd :  testfolder' -> Access Access. TestUser, 250 CWD 명령 성공. "/"는 현재 디렉토리입니다.
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에 항상 연결되면 항상 NULL, NewServerPath의 값은 "/"이며 getPathandFilename ()라는 기능으로 계산됩니다 (이 코드 블록 전에 몇 줄을 호출 함). getPathandFilename ()는 'ftp : // ....'uri의 끝에 경로가 제공되지 않거나 "/"가 명시 적으로 태클 된 경우 NewserverPath를 "/"로 계산합니다.

물론 이것은 궁극적으로 CWD 명령이 null! = "/"이므로 명령 파이프 라인에 추가됩니다.

불행히도 간단히 말해서이 동작은 소스에서 화상을 입었 기 때문에이 동작을 무시할 수 없습니다.

다른 팁

게시물은 오래 전과 비슷하지만 ... 신경 쓰지 마세요. 여기에 답을 제공하겠습니다.

사용하는 대신 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

도움이 되었기를 바랍니다.

나는 우리가 얼마 전에 비슷한 문제를 겪었다고 생각합니다. 그래도 정확한 세부 사항을 기억하지 못합니다.

.NET이 CD 명령을 발행하지 못하도록하려면 작업하려는 디렉토리에 설정된대로 로그인 한 사용자의 기본 디렉토리를 설정하는지 확인하십시오. 명령 줄 FTP 클라이언트를 사용하여이를 확인할 수 있습니다.

다음은 솔루션입니다. C#에서 C#을위한이 무료 오픈 소스 FTP 클라이언트 라이브러리를 사용하여 C-SHARPCORNER.com :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(); 

이 라이브러리는 상자에서 잘 작동하지만 쉽게 확장되고 수정 될 수도 있습니다.

위의 정보를 사용하여 이것은 저에게 효과적이었습니다.

CWD를 보내 -ftpstate.ftprequest = getRequest ( "ftp://192.168.0.2/tmp/file2download")

CWD를 보내지 않습니다 -ftpstate.ftprequest = getRequest ( "ftp://192.168.0.2//tmp/file2download") 서버 IP (또는 이름) 후 //

도트 넷 버전 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top