C#利用 HttpWebRequest 類傳送post請求,出現“套接字(協議/網路地址/埠)只允許使用一次”問題

張利鋒發表於2019-01-14

宣告:問題雖然已經被解決,但是並沒有明白具體原理,歡迎大佬補充。

 

最近網站出現一個問題,在C#裡面使用  HttpWebRequest 類去傳送post請求,偶爾 會出現 “套接字(協議/網路地址/埠)只允許使用一次” 的異常,很明顯應該是埠被佔用。

原因排查:

1、網上說最多就是其他程式佔用埠:因為已經上線,並且有時候可以正常執行,因此排除其他程式佔用埠的可能,而且我網站用的就是80埠。 

2、第二個可能原因就是介面效能較差,佔用較長處理時間:我 給post的目標介面(因為介面也是本身網站提供的,因此可以進行監控) 加上時間日誌,發現處理時長都在 30ms -50 ms 左右,而且網站訪問量並不是很大,因此這個處理速度還是非常快的,按理說不應該出現埠占用情況。

 

我們現在來看一下post程式碼 ,如下:

private string sendHttpWebRequest(bool isPost, string sendData, string requestURL)
    {
        UTF8Encoding encoding = new UTF8Encoding();
        byte[] data = encoding.GetBytes(sendData);
        // 製備web請求
        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(requestURL);
        if (isPost)
        {
            myRequest.Method = "POST";
        }
        else
        {
            myRequest.Method = "GET";
        }
        myRequest.ContentType = "application/x-www-form-urlencoded";
        myRequest.ContentLength = data.Length;
        if (isPost)
        {
            Stream newStream = myRequest.GetRequestStream();
            newStream.Write(data, 0, data.Length);
            newStream.Close();
        }
    }

 

最後 我發現上面的程式碼並沒有接收返回,是因為這個介面本身設計的問題,介面只是為了通知,並不關心返回結果(當然這本身不是一個好的設計) 。

但是經過測試,問題就出在沒有接收返回上,加上接收返回的程式碼以後, “套接字(協議/網路地址/埠)只允許使用一次” 的異常就消失 了!

最後post程式碼如下:

private string sendHttpWebRequest(bool isPost, string sendData, string requestURL)
    {
        UTF8Encoding encoding = new UTF8Encoding();
        byte[] data = encoding.GetBytes(sendData);
        // 製備web請求
        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(requestURL);
        if (isPost)
        {
            myRequest.Method = "POST";
        }
        else
        {
            myRequest.Method = "GET";
        }
        myRequest.ContentType = "application/x-www-form-urlencoded";
        myRequest.ContentLength = data.Length;
        if (isPost)
        {
            Stream newStream = myRequest.GetRequestStream();
            newStream.Write(data, 0, data.Length);
            newStream.Close();
        }
   //獲取響應
  HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
  StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.Default);
   return
reader.ReadToEnd();
}

到此, “套接字(協議/網路地址/埠)只允許使用一次”  這個問題已經不會再出現了。。。 

 

相關文章