由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作。
问题出现在博客抓取程序上。上周五下班前打开的程序,运行了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天以上的,为啥以前没出现…