Есть такая задача:
Написать клиента проверяющего список филиалов одной компании.
Структура веб сервера такова:
Есть страница со списком филиалов, далее вложенные страницы с описанием филиалов
Итак сначала получаем список:
- Код: Выделить всё
private void button1_Click(object sender, EventArgs e)
{
#if(DEBUG)
Stopwatch sw = new Stopwatch();
sw.Start();
#endif
string server = this.textBox1.Text.Trim();
string Get = "GET /filialen.html HTTP/1.1\r\nHost: " + server +
"\r\nUserAgent: Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2) Gecko/20100115 Firefox/3.6\r\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
"Accept-Encoding: gzip,deflate\r\n"+
"Accept-Charset: iso-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
"Connection: Close\r\n\r\n";
Encoding encoding = Encoding.GetEncoding(28591);
Byte[] byteGet = encoding.GetBytes(Get);
Byte[] byteRecv = new Byte[512];
Socket socket = null;
try
{
IPEndPoint hostEndPoint;
IPAddress hostAddress = null;
int hostPort = 80;
IPHostEntry hostInfo = Dns.GetHostEntry(server);
IPAddress[] ipAddresses = hostInfo.AddressList;
for (int index = 0; index < ipAddresses.Length; index++)
{
hostAddress = ipAddresses[index];
hostEndPoint = new IPEndPoint(hostAddress, hostPort);
socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
socket.Connect(hostEndPoint);
if (!socket.Connected)
{
socket = null;
continue;
}
else
{
socket.Send(byteGet, byteGet.Length, 0);
break;
}
}
StringBuilder sb = new StringBuilder(262144);
int byteCount = socket.Receive(byteRecv, byteRecv.Length, 0);
sb.Append(encoding.GetString(byteRecv, 0, byteCount));
while (byteCount > 0)
{
byteCount = socket.Receive(byteRecv, byteRecv.Length, 0);
sb.Append(encoding.GetString(byteRecv, 0, byteCount));
}
#if(DEBUG)
sw.Stop();
this.Text += String.Format(" - Load Page: {0} ms, ", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
#endif
string buff = sb.ToString();
sb.Remove(0, sb.Length);
string fKey = "<div id=\"menuleft\">", lKey = "</div>";
int fKeyPos = buff.IndexOf(fKey, 0);
int lKeyPos = buff.IndexOf(lKey, fKeyPos);
string xml = buff.Substring(fKeyPos, lKeyPos + lKey.Length - fKeyPos);
MemoryStream stream = new MemoryStream(encoding.GetBytes(xml), false);
stream.Seek(0, SeekOrigin.Begin);
TextReader reader = new StreamReader(stream, encoding);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNodeList shops = xmlDoc.SelectNodes("/div/ul/li/a");
foreach (XmlNode shop in shops)
{
sb.AppendFormat("/{0}; {1}\r\n",
shop.Attributes[0].Value, shop.Attributes[2].Value);
}
this.richTextBox1.Text = sb.ToString();
#if(DEBUG)
sw.Stop();
this.Text += String.Format("Formating: {0} ms.", sw.ElapsedMilliseconds);
#endif
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace);
}
finally
{
if (socket != null) socket.Close();
}
}
Мониторинг показал следующие результаты (DSL 16000 | 1.7 Mbit/sec):
Загрузка страницы в среднем - 325 ms.
Форматирование данных в среднем - 12 ms.
Вроде неплохо, но имеется еще (будет больше) 111 страниц с описание филиалов а значит
на загрузку их всех в синхронном режиме уйдет примерно 40 сек. Что конечно неприемлемо.
Хорошо сделаем асинхронную загрузку или много-поточный клиент - допустим выиграем еще 40%
и будем иметь около 24 сек. Тоже жопа.
(Все это конечно относительно т.к. зависит от многих факторов)
Вопрос 1: Как-бы увеличить производительность ?
Вопрос 2: Как-бы Вы, будь вы администратором сайта отреагировали на большое число запросов с одного ип ?
Вопрос 3: Как-бы Вы, будь вы администратором сайта отреагировали на наглую кражу вашего контента ?
Вопрос 4: Как-бы разубедить заказчика от этой идеи и не потерять бабки ?
Буду очень благодарен за дельные советы!