問題出現在博客抓取程序上。上周五下班前打開的程序,運行了2天左右,在這周一中午左右程序報錯。
連主機都DOWN了,系統是WIN SERVER 2003。
錯誤記錄如圖,我也不知道是不是這條有關,不過貌似關系很大。
程序里加了錯誤記錄功能,記錄下的錯誤為:

[Bug] 2012-11-16 20:39:49=System.Net.WebException: 操作已超時。 2012-11-18 9:55:02=System.Net.WebException: 操作已超時。 2012-11-19 10:48:43=System.IO.IOException: 無法從傳輸連接中讀取數據: 遠程主機強迫關閉了一個現有的連接。。 ---> System.Net.Sockets.SocketException: 遠程主機強迫關閉了一個現有的連接。 2012-11-19 11:43:46=System.Net.WebException: 無法連接到遠程服務器 ---> System.Net.Sockets.SocketException: 由於系統緩沖區空間不足或隊列已滿,不能執行套接字上的操作。 202.108.33.48:80 2012-11-19 11:56:10=System.Net.WebException: 基礎連接已經關閉: 無法連接到遠程服務器。 ---> System.Net.Sockets.SocketException: 由於系統緩沖區空間不足或隊列已滿,不能執行套接字上的操作。 2012-11-19 12:56:19=System.Net.WebException: 基礎連接已經關閉: 無法連接到遠程服務器。 ---> System.Net.Sockets.SocketException: 由於系統緩沖區空間不足或隊列已滿,不能執行套接字上的操作。 2012-11-19 13:56:21=System.Net.WebException: 基礎連接已經關閉: 無法連接到遠程服務器。 ---> System.Net.Sockets.SocketException: 由於系統緩沖區空間不足或隊列已滿,不能執行套接字上的操作。 在 System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) 在 System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6, Int32 timeout) 在 System.Net.PooledStream.Activate(Object owningObject, Boolean async, Int32 timeout, GeneralAsyncDelegate asyncCallback) 在 System.Net.Connection.CompleteStartConnection(Boolean async, HttpWebRequest httpWebRequest) --- 內部異常堆棧跟蹤的結尾 --- 在 System.Net.HttpWebRequest.GetResponse() 在 BlogCrawler.InformationRetrivalAssist.GetDataFromUrl(String url, Encoding& encode) 在 BlogCrawler.InformationRetrivalAssist.GetBlogItems(String url, Encoding& m_encode) 在 BlogCrawler.Form1.autoProcessing() 在 System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) 在 System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6, Int32 timeout) 在 System.Net.PooledStream.Activate(Object owningObject, Boolean async, Int32 timeout, GeneralAsyncDelegate asyncCallback) 在 System.Net.Connection.CompleteStartConnection(Boolean async, HttpWebRequest httpWebRequest) --- 內部異常堆棧跟蹤的結尾 --- 在 System.Net.HttpWebRequest.GetResponse() 在 BlogCrawler.InformationRetrivalAssist.GetDataFromUrl(String url, Encoding& encode) 在 BlogCrawler.InformationRetrivalAssist.GetBlogItems(String url, Encoding& m_encode) 在 BlogCrawler.Form1.autoProcessing() 在 System.Net.Sockets.Socket..ctor(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) 在 System.Net.ServicePoint.GetConnection(PooledStream PooledStream, Object owner, Boolean async, IPAddress& address, Socket& abortSocket, Socket& abortSocket6, Int32 timeout) 在 System.Net.PooledStream.Activate(Object owningObject, Boolean async, Int32 timeout, GeneralAsyncDelegate asyncCallback) 在 System.Net.Connection.CompleteStartConnection(Boolean async, HttpWebRequest httpWebRequest) --- 內部異常堆棧跟蹤的結尾 --- 在 System.Net.HttpWebRequest.GetResponse() 在 BlogCrawler.InformationRetrivalAssist.GetDataFromUrl(String url, Encoding& encode) 在 BlogCrawler.InformationRetrivalAssist.GetBlogItems(String url, Encoding& m_encode) 在 BlogCrawler.Form1.autoProcessing() 在 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) 在 System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP) 在 System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception) --- 內部異常堆棧跟蹤的結尾 --- 在 System.Net.HttpWebRequest.GetResponse() 在 BlogCrawler.InformationRetrivalAssist.GetDataFromUrl(String url, Encoding& encode) 在 BlogCrawler.InformationRetrivalAssist.GetBlogItems(String url, Encoding& m_encode) 在 BlogCrawler.Form1.autoProcessing() 在 System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) 在 System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) --- 內部異常堆棧跟蹤的結尾 --- 在 System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size) 在 System.IO.StreamReader.ReadBuffer() 在 System.IO.StreamReader.ReadToEnd() 在 BlogCrawler.InformationRetrivalAssist.GetDataFromUrl(String url, Encoding& encode) 在 BlogCrawler.InformationRetrivalAssist.GetBlogItems(String url, Encoding& m_encode) 在 BlogCrawler.Form1.autoProcessing() 在 System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size) 在 System.IO.StreamReader.ReadBuffer() 在 System.IO.StreamReader.ReadToEnd() 在 BlogCrawler.InformationRetrivalAssist.GetDataFromUrl(String url, Encoding& encode) 在 BlogCrawler.InformationRetrivalAssist.GetBlogItems(String url, Encoding& m_encode) 在 BlogCrawler.Form1.autoProcessing() 在 System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size) 在 System.IO.StreamReader.ReadBuffer() 在 System.IO.StreamReader.ReadToEnd() 在 BlogCrawler.InformationRetrivalAssist.GetDataFromUrl(String url, Encoding& encode) 在 BlogCrawler.InformationRetrivalAssist.GetBlogItems(String url, Encoding& m_encode) 在 BlogCrawler.Form1.autoProcessing()
主要原因就是:
System.Net.WebException: 基礎連接已經關閉: 無法連接到遠程服務器。 ---> System.Net.Sockets.SocketException: 由於系統緩沖區空間不足或隊列已滿,不能執行套接字上的操作。
“這個錯誤可能是你計算機的Socket句柄資源用盡導致的,能夠造成這種現象的一種情況就是你的計算機的某個程序不斷的向某個連接發出連接申請,但是始終沒能連上,沒連上就會引發一個錯誤,如果編程的人沒有寫釋放資源的代碼,那么這個連接就始終占據着着一個句柄,於是由於不斷的連接,最終導致Socket句柄資源耗盡。”
網上搜的,估計就是這個問題。因為每個博客頁面都申請一個Sockets連接,博客這塊兩天下來可能有3W條、服務器上同時跑了微博的、新聞的、百度知道的抓取程序,可能累計申請10W左右連接了把。明天考慮下通過什么顯式的命令在每次處理完抓取后釋放一下Sockets句柄,今天寫專利申請沒時間了。
明天記錄下。
PS:這些程序跑過4天以上的,為啥以前沒出現…