Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Из синхронного сокета в асинхронный  (Прочитано 4645 раз)
0 Пользователей и 1 Гость смотрят эту тему.
nbit
Интересующийся

ru
Offline Offline

« : 28-10-2011 02:05 » 

В MSDN есть замечательный пример получения кода html страницы http://msdn.microsoft.com/ru-ru/library/system.net.sockets.socket.aspx, но к сожалению в этом примере производится блокирование до тех пор, пока не будет принята вся страница. Если не сложно помогите пожалуйста переделать его под асинхронные сокеты, буду премного благодарен за помощь.

Код: (C#)
using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

public class GetSocket
{
    private static Socket ConnectSocket(string server, int port)
    {
        Socket s = null;
        IPHostEntry hostEntry = null;

        // Get host related information.
        hostEntry = Dns.GetHostEntry(server);

        // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
        // an exception that occurs when the host IP Address is not compatible with the address family
        // (typical in the IPv6 case).
        foreach(IPAddress address in hostEntry.AddressList)
        {
            IPEndPoint ipe = new IPEndPoint(address, port);
            Socket tempSocket =
                new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            tempSocket.Connect(ipe);

            if(tempSocket.Connected)
            {
                s = tempSocket;
                break;
            }
            else
            {
                continue;
            }
        }
        return s;
    }

    // This method requests the home page content for the specified server.
    private static string SocketSendReceive(string server, int port)
    {
        string request = "GET / HTTP/1.1\r\nHost: " + server +
            "\r\nConnection: Close\r\n\r\n";
        Byte[] bytesSent = Encoding.ASCII.GetBytes(request);
        Byte[] bytesReceived = new Byte[256];

        // Create a socket connection with the specified server and port.
        Socket s = ConnectSocket(server, port);

        if (s == null)
            return ("Connection failed");

        // Send request to the server.
        s.Send(bytesSent, bytesSent.Length, 0);  

        // Receive the server home page content.
        int bytes = 0;
        string page = "Default HTML page on " + server + ":\r\n";

        // The following will block until te page is transmitted.
        do {
            bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
            page = page + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
        }
        while (bytes > 0);

        return page;
    }

    public static void Main(string[] args)
    {
        string host;
        int port = 80;

        if (args.Length == 0)
            // If no server name is passed as argument to this program,
            // use the current host name as the default.
            host = Dns.GetHostName();
        else
            host = args[0];

        string result = SocketSendReceive(host, port);
        Console.WriteLine(result);
    }
}
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 28-10-2011 07:24 » 

nbit, так в параллельный поток запусти или через System.Threading.Task асинхронную задачу (если .NET 4.x). Только что это тебе даст? Основной поток у тебя ничего не делает. Следовательно последние две строчки кода потребуют синхронизации этих потоков. Тогда какой смысл огород городить?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
nbit
Интересующийся

ru
Offline Offline

« Ответ #2 : 28-10-2011 07:58 » 

Да мне не на потоках надо, а с помощью асинхронных сокетов, т.к. будет десятки запросов в секунду, я именно их и выбрал из-за того что можно сделать высокопроизводительное приложение на их основе.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 28-10-2011 10:15 » 

nbit, надеюсь ты не путаешь два термина: асинхронный ввод-вывод и неблокируемый. Асинхронный как раз блокируемый и под его обслуживание ОС создает отдельный поток. Неблокируемый ввод-вывод можно осуществлять в рамках одного потока.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 28-10-2011 10:50 » 

nbit, может тогда ты задачу опишешь, а мы решение посоветуем.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
nbit
Интересующийся

ru
Offline Offline

« Ответ #5 : 28-10-2011 11:30 » 

да задача простая, мне просто нужно получить html-код страницы (пишу crawler), но не одной, а сразу очень многих, так чтобы по максимуму загрузить канал насколько это возможно. У меня почти все уже сделано, но я реализовал на обычном WebRequest'e и в 1 поток что очень медленно (тестово), если же создавать каждый запрос в отдельном потоке ресурсов компьютера просто не хватит учитывая очень большое количество запросов.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 28-10-2011 12:21 » 

Почему же не хватит? Всем хватает, а тебе не хватит Улыбаюсь

Что нужно хранить для одного запроса?
Данные состояния уровня сокета. Данные состояния уровня HTTP. Данные уровня приложения.
Код потока должен работать с этими данными.
Соотв., запускаешь N  потоков с N блоками данных.
Можно и в один поток, если код у тебя написан как конечный автомат.
« Последнее редактирование: 28-10-2011 12:29 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
nbit
Интересующийся

ru
Offline Offline

« Ответ #7 : 28-10-2011 12:35 » 

Для каждого потока ОС минимум выделяет 1Мб памяти, при 1000-2000 запросов соответственно будут большие накладные расходы (1-2Гб). А насчет асинхронных и не блокируемых я что то окончательно запутался, здесь http://hashcode.ru/questions/47841/%D0%B8%D0%B7-%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D1%81%D0%BE%D0%BA%D0%B5%D1%82%D0%B0-%D0%B2-%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9 ответили что это одно и то же.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 28-10-2011 14:49 » 

Цитата: nbit
А насчет асинхронных и не блокируемых я что то окончательно запутался
Асинхронный - это в параллельном потоке. Тот же BeginConnect запускает Connect в отдельном потоке, а EndConnect получает результат.

Неблокирующая операция ввода-вывода - это другое. Для этого не создаётся отдельных потоков, а на уровне ядра операционной системы происходит управление устройствами ввода-вывода, работа которых на порядки медленнее работы центрального процессора. За ввод-вывод отвечают соответствующие устройства компьютера и их драйверы. Результаты (в твоём случае ввода) накапливаются в очередях и по окончании операции возникает событие готовности, что операция завершена. При помощи специальных средств программа, работающая в 1 поток на процессоре, может обслуживать множество параллельных операций ввода-вывода. В основном обслуживание заключается в запуске нескольких неблокирующих операций чтения, обработки результатов по мере готовности и запуске неблокирующих операций записи. Это делается в цикле. Сам этот подход к обработке называется мультиплексированием. Чем-то это похоже на жонглёра, который подбрасывает тарелочки: пока бОльшая часть тарелочек летит в воздухе, он обслуживает лишь одну (ловит и подбрасывает на новый круг), при этом работа жонглёра строго последовательна, но все тарелочки движутся параллельно.

Что же касается AsyncConnect, то по большому счёту это мало отличается от Begin/EndConnect. Разница может быть в том, что в одном случае запускается новый поток, а в другом - используется механизм заданий для системного пула потоков (к сожалению, в MSDN на уровне описания класса этот вопрос не раскрыт).

Работа с пулом потоков имеет меньше накладных расходов (поскольку нет запуска новых потоков), но при этом количество потоков ограничено (по умолчанию 25), и сами задания выстраиваются в очередь. Короче говоря, параллельно будут работать лишь столько заданий, сколько есть потоков, а остальные будут отложены. Как я понимаю, это не то, что тебе нужно.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
inputdtd
Новенький

ru
Offline Offline

« Ответ #9 : 28-10-2011 15:29 » 

Пришлось зарегится. Что бы мои недруги не расслаблялись.

Цитата: nbit
А насчет асинхронных и не блокируемых я что то окончательно запутался

Что же касается AsyncConnect, то по большому счёту это мало отличается от Begin/EndConnect. Разница может быть в том, что в одном случае запускается новый поток, а в другом - используется механизм заданий для системного пула потоков (к сожалению, в MSDN на уровне описания класса этот вопрос не раскрыт).


Разница есть и существенная.  Вот тут можно посмотреть: http://msdn.microsoft.com/ru-ru/magazine/cc163356.aspx

У меня сервер на асинхронных сокетах работал при 30 тысячах подключений. Так што срач не влетел. Жжешь
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 29-10-2011 12:09 » 

Цитата: inputdtd
Что бы мои недруги не расслаблялись.
Это кто? Здесь недругов не водится Улыбаюсь

Цитата: inputdtd
Замечательно. Если мультиплексирование поддерживается Async-методами в 3.5, то стоит воспользоваться.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines