0

下午好。我为我的英语本身从乌克兰道歉并且说得不好))我有以下问题,我的程序在不同的网址上提出请求,然后从答案中解析一些信息。网址数量超过数百万。为了快速处理,我使用了很多线程,有时大约 500-700 个线程。在某些机器上程序运行良好,但有些机器上会出现错误。像这样的错误:System.Net.Sockets.SocketException (0x80004005): The remote host forcibly broke the existing connection.

我的代码:

void _thread()
{
while(true)
{
string request =
"POST http://" + hostf + "/ HTTP/1.1\r\n" +
"Host: " + host +
"\r\nConnection: Close\r\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
"Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3\r\n" +
"Content-Length: " + ByteArr.Length +
"\r\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n\r\n" +
parametres;

Byte[] bytesSent = Encoding.GetEncoding("UTF-8").GetBytes(request);
Byte[] bytesReceived = new Byte[256];
Socket s = null;
IPHostEntry hostEntry = null;
hostEntry = Dns.GetHostEntry(host);
foreach (IPAddress address in hostEntry.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, 80);
Socket tempSocket =new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tempSocket.Connect(ipe);
if (tempSocket.Connected)
{
s = tempSocket;
break;
}
else
{
continue;
}
}
if (s == null)
continue;
s.Send(bytesSent, bytesSent.Length, 0);
int bytes = 0;
string page = "";
do
{
bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
page = page + Encoding.GetEncoding("UTF-8").GetString(bytesReceived, 0, bytes);
}
while (bytes > 0);
s.Shutdown(SocketShutdown.Both);
s.Close();
//here some work whith page content
}
}

如您所见,每个线程在每次迭代中创建套接字、发送请求、然后获取答案并关闭套接字等等。每个线程打开自己的套接字并使用不同的 url,但在某些机器上,当线程数超过某个数字时,错误开始并且所有套接字都无法正常工作。有人可以帮我一些建议,为什么会这样?有些机器对连接有某种限制或什么?谢谢大家。

4

1 回答 1

0

不要关机(两者);紧随其后。删除 s.shutdown() 并离开 s.Close() 然后尝试。我想我记得关闭两者都使套接字描述符可供使用,因此在下一次关闭时,您可以关闭其他一些套接字,而不是您拥有的套接字。

编辑:一些代码修改:

我会增加一点接收缓冲区

bytes[] bytesReceived = new bytes[1024];

此外,在发送请求字符串时,请告诉接收方您已完成:

s.Send(bytesSent, bytesSent.Length, 0);
// Tell the receiver we are done sending data
s.Shutdown(SocketShutdown.Send);

您还必须在读取套接字并使用 StringBuilder 而不是 String 时检查错误(它比 String 附加文本更快):

StringBuilder page = new StringBuilder();
do
{
    bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
    if (bytes == -1)
    {
         // Error in socket, quit
         s.Close();
         return;
    }
    else if (bytes > 0)
         page.Append(Encoding.GetEncoding("UTF-8").GetString(bytesReceived, 0, bytes));
}
while (bytes > 0);

最后,只需关闭套接字:

// s.ShutDown(Socketshutdown.Both);
s.close();

您可以尝试进行此修改,看看是否已解决。

于 2013-07-27T18:56:29.750 回答