2009-11-13 64 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; 
} 
相关问题