2009-11-13 127 views
1

我試圖從FTP服務器檢索文件列表,但我收到了一些奇怪的非ASCII響應。從C#中的FTP服務器中檢索文件列表

這裏是我使用的代碼:

WRITE:PASV 

READ:227 Entering Passive Mode (10,0,2,24,5,119)` 

WRITE:LIST *.dat 

READ:150 Opening ASCII mode data connection for /bin/ls. 

READ:226 Transfer complete. 

它停在那裏:

public string[] getFileList(string mask) 
{ 
    if(!logined) 
    { 
    login(); 
    } 
    Socket cSocket = createDataSocket(); 
    this.getSslDataStream(cSocket); 
    sendCommand("PASV"); 
    sendCommand("LIST " + "*"+mask); 
    stream2.AuthenticateAsClient(remoteHost, 
     null, 
     System.Security.Authentication.SslProtocols.Ssl3 | 
     System.Security.Authentication.SslProtocols.Tls, 
     true); 
    if(!(retValue == 150 || retValue == 125)) 
    { 
    throw new IOException(reply.Substring(4)); 
    } 
    StringBuilder mes = new StringBuilder();  
    while(true) 
    { 
    int bytes = cSocket.Receive(buffer, buffer.Length, 0); 
    mes.Append(ASCII.GetString(buffer, 0, bytes)); 
    if(bytes < buffer.Length) 
    { 
     break; 
    } 
    } 
    string[] seperator = {"\r\n"}; 
    string[] mess = mes.ToString().Split(seperator, StringSplitOptions.RemoveEmptyEntries); 
    cSocket.Close(); 
    readReply(); 
    if(retValue != 226) 
    { 
    throw new IOException(reply.Substring(4)); 
    } 
    return mess; 
} 

我從FTP服務器上得到的迴應是這樣的。它返回的字符串數組包含一個帶有一些非ascii字符的索引。看起來像一堆垃圾。也許我的ASCII.GetString部分是錯誤的?我不太確定。

在此先感謝。

+0

您使用的是什麼版本的.NET Framework? – Kev 2009-11-13 17:17:09

+0

對不起。 3.5。 – Aaron 2009-11-13 17:17:30

+0

只是一個評論...我可以正確下載和上傳文件。列出並返回列表似乎是我不能做的唯一事情。我試過LS,LIST和NLST。由於某種原因LS不被識別,並且LIST和NLST都是這樣做的。 – Aaron 2009-11-13 17:27:40

回答

4

值得一提的是,System.Net命名空間有以.Net 2.0開頭的FtpWebRequestFtpWebResponse類。

下面是一些代碼,我使用的服務器的文件寫入到本地文件:

... 
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(address); 
ftpRequest.Credentials = new NetworkCredential(username, password); 
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 
ftpRequest.KeepAlive = false; 

FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); 

sr = new StreamReader(ftpResponse.GetResponseStream()); 
sw = new StreamWriter(new FileStream(fileName, FileMode.Create)); 

sw.WriteLine(sr.ReadToEnd()); 
sw.Close(); 

ftpResponse.Close(); 
sr.Close(); 
... 
+0

我知道。我使用了2年前編寫的一些代碼,但在其他程序中上傳和下載時可以正常工作。我想盡可能使用相同的代碼。 – Aaron 2009-11-13 17:33:43

+0

我不會重寫所有 - 只是列出文件。 – 2009-11-13 17:40:11

+0

好的。我試過了,但是我的URI給出了一個未知的格式異常。它應該只是我的ftp服務器名稱? – Aaron 2009-11-13 17:47:46

6

我寫了一個很容易使用包裝庫所有的FtpWebRequest的東西。如果你想看看它,這是在這裏https://gist.github.com/1242616

我在很多生產環境中使用它,它並沒有讓我失望。

0
public Socket BuildDataConn(Socket FirstSocket) 
{ 
    string ret = ""; 
    string RemoteIP = ""; 
    int RemotePort = 0; 
    SendCommand("PASV"); 

    int id = 0; 
    id = strMsg.LastIndexOf(')'); 
    if (id != 0) 
    { 
     string tmp = strMsg.Substring(strMsg.LastIndexOf('(') + 1, id - strMsg.LastIndexOf('(') - 1); 
     string[] bByte = tmp.Split(','); 
     RemotePort = int.Parse(bByte[4]) * 256 + Byte.Parse(bByte[5]); 
     RemoteIP = bByte[0]+"." + bByte[1] + "." + bByte[2] + "." + bByte[3]; 
    } 
    Socket NewConn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    IPEndPoint RemoteIPPort = new IPEndPoint(IPAddress.Parse(RemoteIP), RemotePort); 
    try 
    { 
     NewConn.Connect(RemoteIPPort); 
    } 
    catch 
    { 
     throw new IOException("unable to Connect !"); 
    } 
    return NewConn; 
} 

而不是使用cSocket接收響應數據,你需要獲得一個第二插座,然後使用套接字來接收響應數據。第二個套接字將響應發回信息。在發送命令LIST之前,確保你已經改變了你的FTP工作目錄。

public List<string> GetFileNames() 
{ 
    if (!bConnected) 
    { 
     Open(); 
    } 
    List<string> retObj = new List<string>(); 
    Socket dataSock = BuildDataConn(mySocket); 

    SendCommand("NLST"); 
    string dataSockMsg = ""; 
    buffer = new byte[BLOCK_SIZE]; 

    while (true) 
    { 
     int iBytes = dataSock.Receive(buffer, buffer.Length, 0); 
     dataSockMsg += System.Text.Encoding.ASCII.GetString(buffer, 0, iBytes); 
     if (iBytes < buffer.Length) 
     { 
      break; 
     } 
    } 

    string[] message = dataSockMsg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);  

    dataSock.Close(); 

    foreach (string obj in message) 
    { 
     retObj.Add(obj); 
    } 

    return retObj; 
} 
相關問題