簡體   English   中英

嘗試上傳到FTP:System.Net.WebException:系統錯誤

[英]Attempting to upload to FTP: System.Net.WebException: System error

我有一個接受XML的API,並最終根據XML中的信息上傳文件。 上傳是按計划進行的(也來自XML),我已經測試了周圍的所有內容,並且知道它可以工作。

在每個時間周期內嘗試上載的第一個文件時,大約40%的時間出現錯誤(某些文件的時間周期= 45分鍾,其他文件的時間周期= 30分鍾)。

這是我上傳的代碼:

try {
    LoggerFTP.Log("Uploading file: " + filename, false);

    // Create the request.
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(appSettingsFTP.ftpUrl + @"/" + filename);
    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.Timeout = 6000000; //set to 100 minutes
    //request.Timeout = -1; //set to infinite

    // Add the login credentials.
    request.Credentials = new NetworkCredential(appSettingsFTP.ftpLogin, appSettingsFTP.ftpPassword);

    // Grab the file contents.
    StreamReader sourceStream = new StreamReader(appSettingsFTP.uploadFileDirectory + filename);
    byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
    sourceStream.Close();
    request.ContentLength = fileContents.Length;

    // Copy the file contents to the outgoing stream.
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(fileContents, 0, fileContents.Length);
    requestStream.Close();

    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    //Logger.Log(filename.ToString() + " " + "Upload Complete, Status: " + response.StatusCode + " " + response.StatusDescription, false);
    //Took response.StatusDescription out because it appears to be creating extra line feeds.
    LoggerFTP.Log(filename.ToString() + " " + "Upload Complete, Status: " + response.StatusCode, false);
}
catch (Exception ex) {
    LoggerFTP.Log(ex.ToString(), false);
}

我已經研究了這個問題,並在網上看到了一些可能是速度問題的信息。 就像有一個超時。 但是我將FtpWebRequest的超時設置為100分鍾,所以可能不是嗎? 我不知道。 它也作為服務運行,因此很難測試代碼的這一方面。

這是我的記錄器(e.ToString)中記錄的異常:

System.Net.WebException: System error. ---> System.Net.InternalException: System error.
   at System.Net.PooledStream.PrePush(Object expectedOwner)
   at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
   at System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)
   at System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
   at System.Net.FtpWebRequest.RequestCallback(Object obj)
   at System.Net.CommandStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at System.IO.Stream.Dispose()
   at System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
   at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
   at System.Net.FtpWebRequest.AttemptedRecovery(Exception e)
   at System.Net.FtpWebRequest.SubmitRequest(Boolean async)
   --- End of inner exception stack trace ---
   at System.Net.FtpWebRequest.GetRequestStream()
   at CPMainSpringAPIExportsSC.UploadFTP.FTPUploadMethod(String viewname, String filename)

我在嘗試通過SSL進行FTP的SSIS包中得到了完全相同的堆棧跟蹤。 如果沒有SSL,它會很好用,但是一旦啟用SSL,它就會崩潰。

    System.Net.WebException: System error. --->
    System.Net.InternalException: System error.    at
    System.Net.PooledStream.PrePush(Object expectedOwner)    at
    System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)    at
    System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)    at
    System.Net.FtpWebRequest.SyncRequestCallback(Object obj)    at
    System.IO.Stream.Close()    at
    System.Net.ConnectionPool.Destroy(PooledStream pooledStream)    at
    System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)    at
    System.Net.FtpWebRequest.AttemptedRecovery(Exception e)    at
    System.Net.FtpWebRequest.SubmitRequest(Boolean async)
    --- End of inner exception stack trace ---    at
    System.Net.FtpWebRequest.CheckError()    at
    System.Net.FtpWebRequest.GetRequestStream()    at
    ST_0ff7348de65a468bb358ab0206e3721f.ScriptMain.Main() in c:\Users\Stephens\AppData\Local\Temp\Vsta\e664c8a71bb647ff9e9dc6ac32d7b615\ScriptMain.cs:line 155 at 
    System.Net.FtpWebRequest.CheckError()    at
    System.Net.FtpWebRequest.GetRequestStream()    at
    ST_0ff7348de65a468bb358ab0206e3721f.ScriptMain.Main() in c:\Users\Stephens\AppData\Local\Temp\Vsta\e664c8a71bb647ff9e9dc6ac32d7b615\ScriptMain.cs:line 155

由於該錯誤是如此普遍,因此我決定查看.NET源代碼,以了解是否可以了解中斷的線索。 如果您去這里:

http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Net#{%22pageClientState%22%3A%22type-2844%2Ccsharp%22}

並跳至第281行,您將看到內部void PrePush(object ExpectedOwner)的定義,該定義在發生異常時正在執行。 看起來像這樣:

    internal void PrePush(object expectedOwner)
    {
        lock (this) {
            //3 // The following tests are retail assertions of things we can't allow to happen.
            if (null == expectedOwner) {
                if (null != m_Owner && null != m_Owner.Target)
                    throw new InternalException();
                // new unpooled object has an owner
            }
            else {
                if (null == m_Owner || m_Owner.Target != expectedOwner)
                    throw new InternalException();
                // unpooled object has incorrect owner
            }

            m_PooledCount++;

            if (1 != m_PooledCount)
                throw new InternalException();
            // pushing object onto stack a second time
            if (null != m_Owner)
                m_Owner.Target = null;
        }
    }

最終,我發現FtpWebRequest僅支持顯式FTP(端口21),而不支持隱式FTP(端口990)。 明確地在這里指出:

.NET FtpWebRequest是否支持隱式(FTPS)和顯式(FTPES)?

無論如何,就我而言,這是一個防火牆問題。 最初,我們為隱式FTP配置了端口989、990、49152-65535(根據供應商的技術人員)。 我檢查了我的網絡人員,並打開了端口20、21、989、990和40000-655535,明確了這些內容,然后事情就如冠軍一般了。

但是,就您而言,似乎似乎有些連接池令人興奮。 這里有關於這個主題的好文章:

如何提高FtpWebRequest的性能?

您可能想看看設置連接池的過程,看看是否可以取得一些進展。 希望這可以幫助!

問候,

斯圖爾特

我知道這是一個老話題,但是對於任何有相同問題的人,缺少的代碼是:

            request.EnableSsl = false;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM