2011-04-06 129 views
0

我必須從FTP服務器獲取文件,但我遇到了一些特定的問題。代碼的總體思路是我必須登錄三次,然後從服務器獲取文件列表。通過罰款,但是當我去的兩個文件,我需要我得到一個SocketException:「建立的連接被您的主機中的軟件中止」原始FTP從被動服務器C下載文件#

要清楚,第一個文件不會生成此異常,但它也不下載任何東西。第二個完全失敗。

代碼如下:

static void Main(string[] args) 
    { 
     IPHostEntry dns = Dns.GetHostEntry("SERVER"); 

     IPEndPoint serverIP = new IPEndPoint(dns.AddressList[0], 21); 

     Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 


     sock.Connect(serverIP); 

     FTPRequest("USER firstusername\n", sock); 
     FTPRequest("PASS firstpass\n", sock); 
     FTPRequest("USER secondusername\n", sock); 
     FTPRequest("PASS secondpass\n", sock); 
     FTPRequest("USER thirdusername\n", sock); 
     FTPRequest("PASS thirdpass\n", sock); 
     FTPRequest("TYPE A\n", sock); 
     string s = FTPRequest("PASV\n", sock); 
     IPEndPoint listenIP = IPEnd(s); 
     Socket sock2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     sock2.Connect(listenIP); 
     FTPRequest("LIST\n", sock); 


     ArrayList al = new ArrayList(); 


     try 
     { 
      byte[] buffer = new byte[25000]; 

      int bytes = 0; 

      bytes = sock2.Receive(buffer); 

      Thread.Sleep(1000); 

      string stringList = Encoding.ASCII.GetString(buffer, 0, bytes); 



      foreach (string st in stringList.Split(' ', '\n')) 
      { 
       if (st.Contains(".CSV")) 
        al.Add(st.Trim()); 
      } 
     } 
     catch (Exception) 
     { 
      return; 
     } 

     sock2.Disconnect(false); 

     DateTime dt = new DateTime(); 

     foreach (string st in al) 
     { 
      DateTime temp = DateTime.ParseExact(st.Split('_', '.')[4], "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture); 
      if (temp > dt) 
       dt = temp; 
     } 

     string file1 = ""; 
     string file2 = ""; 

     foreach (string st in al) 
     { 
      if (st.Contains(dt.ToString("yyyyMMdd"))) 
      { 
       if (st.Contains("CAN")) 
        file1 = st; 
       else 
        file2 = st; 
      } 
     } 

     FTPRequest("TYPE I\n", sock); 

     foreach (string file in new string[] { file1, file2 }) 
     { 
      if (file != "") 
      { 
       Socket sock3 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

       FTPRequest("TYPE I\n", sock); 
       sock3.Connect(IPEnd(FTPRequest("PASV\n", sock))); 

       FTPRequest("RETR" + file + '\n', sock); 

       try 
       { 
        byte[] buffer = new byte[25000]; 

        int bytes = 0; 

        bytes = sock3.Receive(buffer); 


        FileStream writeStream = new FileStream(@"MYPATH" + file1, FileMode.Create); 

        while (bytes > 0) 
        { 
         writeStream.Write(buffer, 0, bytes); 
         bytes = sock3.Receive(buffer, 0); 
        } 


       } 
       catch (Exception) 
       { 
        return; 
       } 
       finally 
       { 
        sock3.Disconnect(false); 
       } 
      } 
     } 

     sock.Disconnect(false); 
     Console.Read(); 

    } 


    static string FTPRequest(string command, Socket sock) 
    { 
     string resp = string.Empty; 
     Byte[] bytesReceived = new Byte[1024]; 
     int bytes = 0; 

     Byte[] bytesSent = Encoding.ASCII.GetBytes(command); 
     sock.Send(bytesSent, bytesSent.Length, 0); 

     Thread.Sleep(1000); 

     try 
     { 
      bytes = sock.Receive(bytesReceived, bytesReceived.Length, 0); 
     } 
     catch (Exception) 
     { 
     } 
     return Encoding.ASCII.GetString(bytesReceived, 0, bytes); 
    } 

    static IPEndPoint IPEnd(string pasvResponse) 
    { 
     string s = pasvResponse.Split(' ')[4]; 
     s = s.Trim(); 
     s = s.Trim('(', ')'); 
     string[] sp = s.Split(','); 
     IPHostEntry dns = new IPHostEntry(); 
     try 
     { 
      dns = Dns.Resolve(string.Format("{0}.{1}.{2}.{3}", sp[0], sp[1], sp[2], sp[3])); 
     } 
     catch (Exception) 
     { 
     } 
     int port = int.Parse(sp[4]) * 256 + int.Parse(sp[5]); 
     return new IPEndPoint(dns.AddressList[0], port); 
    } 

我是一個有點新的使用C#的FTP東西,所以任何幫助是非常讚賞。

回答

3

我建議直接使用FtpWebRequest來從FTP服務器獲取信息。導致錯誤的可能性要小得多,因爲它是核心框架中非常強大的一部分。

+1

我會這樣做,但我不知道重複提交憑證的方法。不過,我可能是錯的,因爲我還是這個新手。 – SeanVDH 2011-04-06 16:12:24

+0

@SeanVDH:如果它是一個真正的FTP服務器,你不需要。如果不是這樣,我更擔心服務器爲什麼要這樣做,而不是如何解決它...... – 2011-04-06 16:14:32

+0

我更多地指的是我必須提交的三個憑證。我相信我實際上必須通過某種代理連接。 – SeanVDH 2011-04-06 16:48:34