宣告:問題雖然已經被解決,但是並沒有明白具體原理,歡迎大佬補充。
最近網站出現一個問題,在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();
}
到此, “套接字(協議/網路地址/埠)只允許使用一次” 這個問題已經不會再出現了。。。