HttpWebRequest 基礎連接已經關閉: 接收時發生錯誤


HttpWebRequest request = null;
            Stream webStream = null;
            HttpWebResponse response = null;
            StreamReader reader = null;
            string responseString = "";

            try
            {
                byte[] bf = Encoding.UTF8.GetBytes(postString);
                request = WebRequest.Create(url) as HttpWebRequest;
                request.Method = "POST";
                request.ServicePoint.Expect100Continue = false;
                request.Timeout = 1000 * 3;
                request.ContentType = "application/x-www-form-urlencoded";
                request.KeepAlive = false;
                request.ProtocolVersion = HttpVersion.Version11;  
                request.ContentLength = bf.Length;
                webStream = request.GetRequestStream();
                webStream.Write(bf, 0, bf.Length);

                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);

                responseString = reader.ReadToEnd();

                Log.Info(responseString);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                request.Abort();
                request = null;
                if (webStream != null)
                {
                    webStream.Close();
                }
                if (reader != null)
                {
                    reader.Close();
                }
                if (response != null)
                {
                    response.Close();
                    response = null;
                }
            }

            

            //解析
            JavaScriptSerializer jsonConvert = new JavaScriptSerializer();
            dynamic responseObj = jsonConvert.DeserializeObject(responseString);
            if (responseObj is Dictionary<string, object>)
            {
                Dictionary<string, object> jsonobj = (Dictionary<string, object>)responseObj;
                message.ResponseMessage = string.Format("[{0}]"+jsonobj["ResultDesc"].ToString(),DateTime.Now.ToString());
            }
View Code

 

在調試短信通信接口的時候出現 “基礎連接已經關閉: 接收時發生錯誤”

研究很長時間 ,沒找到原因,查找網上解決方案,其中一位仁兄的方案提供了幫助,這里友情連接一下:http://blog.csdn.net/liehuo123/article/details/7071636

 

總結一下原因,可能是必須指定雙方http協議相同。

網上還有其他的解決方案,如

MyRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";

這個沒試過。

諸君如果以上方式不能解決,請請教百度君。

補充 :

http://www.cnblogs.com/1971ruru/archive/2012/04/11/2442589.html

http://www.cnblogs.com/1971ruru/archive/2012/04/11/2442593.html

http://www.cnblogs.com/1971ruru/archive/2012/04/11/2442665.html

http://blog.sina.com.cn/s/blog_3eea4f680100s48d.html

這個總結的比較多:

http://www.crifan.com/fixed_problem_sometime_httpwebrequest_getresponse_timeout/

 

【總結】

此處GetResponse超過的原因是,當前存在太多數目的alive的http連接(大於10個),所以再次提交同樣的http的request,再去GetResponse,就會超時死掉。

解決辦法就是,把DefaultConnectionLimit 設置為一個比較大一點的數值,此數值保證大於你當前已經存在的alive的http連接數即可。

【經驗總結】

以后寫http的request代碼,如果不是必須的要keepalive的,那么就要設置KeepAlive為false:

req.KeepAlive = false;

以及做對應的收尾動作:

if (resp != null) 
{ 
    resp.Close(); 
} 
if (req != null) 
{ 
    req.Abort(); 
}
 

 

【后記 2012-03-01】

又偶爾遇到一次,DefaultConnectionLimit已經是200了,足夠大了,但是GetResponse和GetRequestStream,還是會超時死掉的問題,具體是什么原因導致的還不是很清楚,但是經過折騰,參考:

HttpWebResponse’s GetResponse() hangs and timeouts

在:

req = (HttpWebRequest)WebRequest.Create(constSkydriveUrl); 
setCommonHttpReqPara(ref req); 
resp = (HttpWebResponse)req.GetResponse();
 

之前,添加一句垃圾回收:

System.GC.Collect();

然后就解決了GetResponse的超時問題,並且后面的GetRequestStream也同時可以正常工作,不超時了。

所以,看起來像是當前系統由於調試多次,並且HttpWebRequest和HttpWebResponse都是沒有正常去Close的,可能會殘留一些http的鏈接,然后就可能影響到了后續對於http的使用,垃圾回收后,估計就把殘余的http相關資源釋放了,然后http就可以正常工作了。

 

【總結】

對於GetResponse或GetRequestStream超時死掉的原因,可能是:

1.DefaultConnectionLimit是默認的2,而當前的Http的connection用完了,導致后續的GetResponse或GetRequestStream超時死掉

==>> 默認系統只支持同時存在2個http的connection 

==>> 使用HttpWebRequest之后如果沒有close,則會占用1個http的connection,所以如果超過2次使用HttpWebRequest而沒有close,那么就用完系統的http的connection,之后再去使用HttpWebRequest,GetResponse就會死掉

解決辦法:

辦法1:

每次使用完HttpWebRequest,使用

?1
2 req.Close(); req=null; 
去關閉對應的http connection

最好對應的HttpWebResponse也要close:

?1
2 resp.Close(); resp = null; 
方法2:

修改DefaultConnectionLimit的值,改為足夠大,比如:

?1 System.Net.ServicePointManager.DefaultConnectionLimit = 200; 
 

2.系統中Http相關的資源沒有正確釋放,導致后續GetResponse或GetRequestStream超時死掉

就像我此處遇到的,可能是之前調用http相關函數,沒有正確完全釋放資源,導致雖然DefaultConnectionLimit給了足夠大,但是還是會死掉,此時在http請求代碼之前去做一次垃圾回收,則后續http的GetResponse或GetRequestStream就正常了,就不會超時死掉了。

參考代碼如下:

?1
2
3
4
5 System.GC.Collect();   req = (HttpWebRequest)WebRequest.Create(constSkydriveUrl); setCommonHttpReqPara(ref req); resp = (HttpWebResponse)req.GetResponse(); 
 

3.Http的GET請求時,不要手動設置ContentLength的值

這個是參考這里:HttpWebRequest.GetResponse() hangs the second time it is called而記錄於此的,也許有人是此原因,所以可供參考一下。

即Http的GET請求,不要添加類似如下的代碼:

?1
2 if (m_contentLength > 0)     httpWebRequest.ContentLength = m_contentLength; 
不要去手動修改對應的ContentLength的值,C#的http相關庫函數,會自動幫你計算的。

注:POST方法中,的確是要手動填充數據和算出數據大小,然后手動給ContentLength賦值的。

 

4.其他可能的一些原因

(1)關於KeepAlive的問題

如果Http的請求,是設置了KeepAlive=true的話,那么對應的http的connection會和服務器保持連接的。

所以如果上述辦法都不能解決超時的問題,可以嘗試將keepAlive設置為false試試,看看能否解決。

(2)關於Sleep

有些人好像是通過在http請求前,加了對應的Sleep,結果解決了此問題。需要的人,也可以試試。

(3)HttpWebRequest的Timeout

一般來說,既然超時了,往往是由於錯誤使用函數或者網絡有問題導致的,所以實際上此處對於有些人去把HttpWebRequest的Timeout的值改的更大,往往都是沒用的。

只不過,萬一是由於網絡響應慢而導致超時,那么倒是可以嘗試,將HttpWebRequest的Timeout的值改為更大。

(其中HttpWebRequest的Timeout默認的值是100,000 milliseconds ==100 seconds)

參考代碼:

?1 req.Timeout = 5 * 60 * 1000; // 5 minutes 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM