用于C#的FTP over SSL

时间:2009-08-31 00:41:09

标签: c# ssl ftp ftps

我正在使用下面的代码(需要是.Net 2.0)在UAT服务器上连接到客户FTP服务器以上/下加载文件。我需要使用他们提供的自签名证书通过端口990进行连接。我已经修改了防火墙规则,允许从我们的UAT服务器连接到端口990上的URI。

然而(!:))我的行超时

 Stream requestStream = request.GetRequestStream();

如果我增加超时时间,则没有区别。

我在网上浏览了一下,但发现代码中没有遗漏任何明显的东西。

如果我使用CuteFTP在UAT服务器上连接,那么,当然它连接正常,我可以手动进行文件传输。如果我使用WireShark来查看网络流量,它会从FTP服务器获得响应,但永远不会为userid和pwd(代码)进行握手,但是通过CuteFTP,所有网络流量都没问题。

我强制返回True,检查证书。


private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                string completeFTPPath = ConfigurationManager.AppSettings["FTPPath"];
                // get the object used to communicate with the server.
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(completeFTPPath);
                request.EnableSsl = true;
                request.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["FtpUserName"], ConfigurationManager.AppSettings["FtpPassword"]);
                request.Method = WebRequestMethods.Ftp.UploadFile;                

                ServicePointManager.ServerCertificateValidationCallback = AcceptAllCertifications;

                // read file into byte array
                StreamReader sourceStream = new StreamReader(ConfigurationManager.AppSettings["LocalFilePath"]);
                byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
                sourceStream.Close();
                request.ContentLength = fileContents.Length;

                // send bytes to server
                MessageBox.Show("GetRequestStream() start");
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(fileContents, 0, fileContents.Length);
                requestStream.Close();
                MessageBox.Show("GetRequestStream() end");

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
                MessageBox.Show("Response status: " + response.StatusDescription);
            }
            catch (WebException we)
            {
                MessageBox.Show(we.Message);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }

        }

  public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
        { return true; }

e.g。 FTPPath - ftp://111.222.333.444:990/UAT/testFile.zip; FtpUserName - userID; FtpPassword = userPwd; LocalFilePath - c:\ temp \ testFile.zip

任何想法?因为有些人似乎有上面的代码工作。 TIA。

5 个答案:

答案 0 :(得分:1)

在端口990上,服务器很可能支持implicit FTPS,而不是更标准的显式FTPS。可能是FtpWebRequest不支持隐式FTPS(我不知道)。

如果是这样,请查看支持隐式和显式FTPS的edtFTPnet/PRO以及SFTP。

答案 1 :(得分:1)

答案 2 :(得分:0)

打开.Net中的跟踪并重新发布问题,然后发布生成的日志,我会告诉你出了什么问题。在.Net 2.0中的FtpWebRequest中存在一些已知问题,因此您可能也会遇到其中一个问题但是不可能仅仅使用您正在显示的代码。有关启用跟踪的说明,请访问:http://blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx

答案 3 :(得分:0)

我原本也看过这个,但它并没有给我带来太多启发。

我刚刚再次运行了跟踪,并在Durgaprasad的帖子中使用了SSL system.diagnostics设置。

System.Net Verbose: 0 : [7016] WebRequest::Create(ftp://www.companyname.com:990/UAT/testFile.zip)
System.Net Information: 0 : [7016] FtpWebRequest#48285313::.ctor(ftp://www.companyname.com:990/UAT/testFile.zip)
System.Net Verbose: 0 : [7016] Exiting WebRequest::Create()     -> FtpWebRequest#48285313
System.Net Verbose: 0 : [7016] FtpWebRequest#48285313::GetRequestStream()
System.Net Information: 0 : [7016] FtpWebRequest#48285313::GetRequestStream(Method=STOR.)
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Socket(InterNetwork#2)
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Socket() 
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Connect(131:990#-2083582714)
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Connect() 
System.Net Information: 0 : [7016] Associating FtpWebRequest#48285313 with FtpControlStream#18796293
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Receive()
System.Net.Sockets Error: 0 : [7016] Exception in the Socket#31914638::Receive - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Receive()   -> 0#0
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Dispose()
System.Net Information: 0 : [7016] FtpWebRequest#48285313::(Releasing FTP connection#18796293.)
System.Net Error: 0 : [7016] Exception in the FtpWebRequest#48285313::GetRequestStream - The operation has timed out.
System.Net Error: 0 : [7016]    at System.Net.FtpWebRequest.GetRequestStream()
System.Net Verbose: 0 : [7016] Exiting FtpWebRequest#48285313::GetRequestStream() 

此外,(在上一次运行此操作时)我让网络团队运行Netmon,他们从下面暗示,它与代码有关:


  TCP    kulccstgweb02:2673     companyname.com:microsoft -ds  ESTABLISHED
  TCP    kulccstgweb02:2678     companyname IP:ftps    ESTABLISHED
  TCP    kulccstgweb02:sms-chat  companyname IP:ftps    ESTABLISHED
BTW,FTPPath - “ftp://111.222.333.444:990/UAT/testFile.zip”实际上是“ftp://www.companyname.com:990/UAT/testFile.zip”,然后解析为IP。但我不知道这会有什么影响。

答案 4 :(得分:0)

使用FTP上传文件时,我通常会创建FtpWebRequest对象,如下所示:

string address = "ftp://www.companyname.com/UAT/"
string fileName = "testFile.zip"
UriBuilder uriBuilder = new UriBuilder(address);
FtpWebRequest  request = (FtpWebRequest)WebRequest.Create(uriBuilder.ToString() + fileName);

尝试一下,看看会发生什么,我知道这适用于显式SSL和端口990。