Асинхронно на сокетах скачать несколько html страничек
Собственно сабж. Если есть пример буду очень благодарен. Везде для сокетов описывается клиент-сервер, никак не могу понять общую картину как это делается, мне просто нужно получить код страницы, неужели для этого нужен клиент-сервер?
UPD: есть пример, но он только для одного запроса
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace AsyncSocketExample
{
public partial class Form1 : Form
{
private delegate void MyDelegate(object args);
public Form1()
{
InitializeComponent();
}
private void GetHtmlAsynh(string adress) //все что в этом методе было раньше в обработчике кнопки
{
if (String.IsNullOrEmpty(adress))
{
MessageBox.Show("Необходимо указать url!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
int port = 80; // по умолчанию порт 80
Uri u = new Uri(textBox1.Text);
// создаем сокет
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// инициализируем обработчик асихронных операций
SocketAsyncEventArgs se = new SocketAsyncEventArgs();
// подключаем обработчики событий асинхронных запросов
se.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
// цепляем точку доступа
IPHostEntry hostEntry = Dns.GetHostEntry(u.Host);
se.RemoteEndPoint = new IPEndPoint(hostEntry.AddressList[0], port);
//se.UserToken = s;
// создаем асихронное подключение
s.ConnectAsync(se);
}
private void button1_Click(object sender, EventArgs e)
{
GetHtmlAsynh(textBox1.Text);
}
// обработчик асинхронных операций
private string _requestResult = "";
private int total = 0;
private void OnSend(object sender, SocketAsyncEventArgs e)
{
Socket s = (Socket)sender; // в sender будет передаваться экземпляр сокета, вызвавшего это событие
// выводим информацию о текущей операции и результатах её выполнения
if (e.SocketError == SocketError.Success)
{
//SetLabel(String.Format("Операция {0} успешно выполнена!", e.LastOperation));
}
else
{
SetLabel(String.Format("Ошибка {1} при выполнении операции {0}...", e.LastOperation, e.SocketError));
}
// --
// делаем что-нибудь, в зависимости от типа выполненной операции
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
// если соединение установлено
if (e.SocketError == SocketError.Success)
{ // отправляем запрос
SendRequest(s, e);
}
break;
case SocketAsyncOperation.Send:
// если запрос отправлен без ошибок
if (e.SocketError == SocketError.Success)
{ // получаем ответ от удаленного сервера
byte[] buffer = new byte[4096];// размер пакета 4 кб
e.SetBuffer(buffer, 0, buffer.Length);
// аннулируем предыдущий результат, если был
_requestResult = "";
total = 0;
// получаем пачку ответа
s.ReceiveAsync(e);
}
break;
case SocketAsyncOperation.Receive:
if (e.SocketError == SocketError.Success)
{
SetLabel(String.Format("Операция {0} успешно выполнена! Получено {1} байт, всего {2} байт", e.LastOperation, e.BytesTransferred, total + e.BytesTransferred));
// передаем результат в TextBox
_requestResult += Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
total += e.BytesTransferred;
// слудующая пачка данных, если есть
if (e.BytesTransferred > 0)
{
// нужно обнулить буфер, иначе куски данных могут попасть в следующий ответ
byte[] buffer = new byte[4096];
e.SetBuffer(buffer, 0, buffer.Length);
s.ReceiveAsync(e);
}
else
{
// нет данных, отключаемся
s.Close();
textBox2.Invoke(new Action(() => { textBox2.Text = _requestResult; }));
}
}
break;
}
}
// метод отправляет запрос
private void SendRequest(Socket s, SocketAsyncEventArgs e)
{
// формируем HTTP-запрос
Uri u = new Uri(textBox1.Text);
string request = "GET " + u.PathAndQuery + " HTTP/1.1\r\nHost: " + u.Host + "\r\nConnection: Close\r\n\r\n";
Byte[] buffer = Encoding.ASCII.GetBytes(request);
e.SetBuffer(buffer, 0, buffer.Length);
// отправляем асинхронный запрос
s.SendAsync(e);
}
// изменение label-а, находящегося в основном потоке
private void SetLabel(object args)
{
if (this.InvokeRequired)
{
this.Invoke(new MyDelegate(SetLabel), args);
return;
}
label2.Text = args.ToString();
}
}
}
Коротко: textBox1
содержит url
, в textBox2
выводится информация (но мне все равно куда, главное - чтобы из каждого сокета, если их несколько, получить информацию).
Подскажите, пожалуйста, как запустить несколько сокетов одновременно и принять данные от них?