Re[5]: Listener без цикла?
От: mDmitriy Россия  
Дата: 13.06.13 11:15
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, mDmitriy, Вы писали:

D>>Мой вопрос касался сугубо клиента.
AVK>Listener это у тебя клиент?
Ну да... Я в сетях не спец, и, возможно, криво выразился.
Имеется ввиду, что клиент посылает серверу запрос и ждет, что тот ему ответит. А ответ может быть долгим и прерывистым. Поэтому надо слушать сокет и собирать данные.
Re[6]: Listener без цикла?
От: matumba  
Дата: 13.06.13 11:34
Оценка: 3 (1)
Здравствуйте, mDmitriy, Вы писали:

D>А ответ может быть долгим и прерывистым. Поэтому надо слушать сокет и собирать данные.


Юзай сокеты, Люк!
Найди любой удобный враппер (чтобы легче читать строки, например) и будет тебе щщастье.
Re[7]: Listener без цикла?
От: mDmitriy Россия  
Дата: 13.06.13 12:11
Оценка:
Здравствуйте, matumba, Вы писали:

M>Здравствуйте, mDmitriy, Вы писали:


D>>А ответ может быть долгим и прерывистым. Поэтому надо слушать сокет и собирать данные.


M>Юзай сокеты, Люк!

M>Найди любой удобный враппер (чтобы легче читать строки, например) и будет тебе щщастье.
Спасибо!
Re[2]: Listener без цикла?
От: mDmitriy Россия  
Дата: 13.06.13 12:12
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, mDmitriy, Вы писали:




D>>Вопрос: нет ли в NET готового сетевого слушателя, чтобы работал как Timer — создал, подписался на событие о поступлении инфы, подключился и счастлив?


S>http://round-angle-net.blogspot.ru/2010/09/tcpip-c.html

S>Смотри ассинхронный BeginAccept
Спасибо! Не по моей теме немножко, но очень хорошая статья.
Re[6]: Listener без цикла?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.06.13 12:47
Оценка:
Здравствуйте, mDmitriy, Вы писали:

D>Имеется ввиду, что клиент посылает серверу запрос и ждет, что тот ему ответит. А ответ может быть долгим и прерывистым. Поэтому надо слушать сокет и собирать данные.


Ну тогда либо BeginRead у NetworkStream, либо ReadAsync если у тебя фреймворк 4.5. Собирать данные все равно при этом придется. Если же нужен прием законченного куска данных и голову не морочить, то тут, емнип, только HTTP стандартно поддерживается в WebClient. Там есть методы, которые сами соображают сколько будет данных и твой код вызовется только при полном завершении передачи.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[6]: Listener без цикла?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.06.13 12:47
Оценка: +2
Здравствуйте, matumba, Вы писали:

M>Нет, только 37.81%; Есть какие-то возражения?


Ну, как бы использование блокирующих вызовов в листенере — не самая лучшая практика. Пул потоков ограничен скромной величиной, а его раздувание весьма прожорливо в плане ресурсов, при ее превышении клиентские запросы будут подвисать. Поэтому рекомендуемая практика — использовать IOCP. Или IOCP тоже идиоты придумали и он не нужен?
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[2]: Listener без цикла?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.06.13 12:48
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Смотри ассинхронный BeginAccept


BeginAccept это серверная сторона. А главное — он не принимает данных. Тебе управление вернется сразу после того как accept клиента отработает, а читать все равно надо ручками из NetworkStream.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[7]: Listener без цикла?
От: matumba  
Дата: 13.06.13 13:11
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Ну, как бы использование блокирующих вызовов в листенере — не самая лучшая практика.


По какой причине? Потому что ты начитался тырнетных экспертов? А эти эксперты различают задачи?

AVK> Пул потоков ограничен скромной величиной


Причём тут потоки? Я про пул ожидающих соединения. ВРЕМЕННО можно допустить, чтобы этот пул был заполнен. А уже потоки разберут этот пул для обслуживания.

AVK> Поэтому рекомендуемая практика — использовать IOCP. Или IOCP тоже идиоты придумали и он не нужен?


Зачем заниматься крысиной демагогией? Где-то я говорил про идиотов или IOCP? Хочешь — используй, каждый сам хозяин своих проблем. Блокирующий слушатель или ридер — наипростейший вариант, почему бы не начать с него?
Re[8]: Listener без цикла?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.06.13 13:18
Оценка: +2
Здравствуйте, matumba, Вы писали:

AVK>>Ну, как бы использование блокирующих вызовов в листенере — не самая лучшая практика.

M>По какой причине? Потому что ты начитался тырнетных экспертов?

По причине того, что схемы с выделением потока на каждого клиента крайне скверно масштабируются.

AVK>> Пул потоков ограничен скромной величиной

M>Причём тут потоки?

Потому что блокирующий Read требует выделения потока на каждый запрос.

M>Блокирующий слушатель или ридер — наипростейший вариант, почему бы не начать с него?


Потому что проблемы начнутся даже на очень скромной нагрузке.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: Listener без цикла?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.06.13 13:21
Оценка:
Здравствуйте, mDmitriy, Вы писали:


S>>http://round-angle-net.blogspot.ru/2010/09/tcpip-c.html

S>>Смотри ассинхронный BeginAccept
D>Спасибо! Не по моей теме немножко, но очень хорошая статья.

http://www.sql.ru/forum/188228/assinhronnye-sokety-vopros-po-teorii
Посмотри там есть и асинхронный клиент и сервер. Но я например использую в начале буфера длину отправленных байт, что бы заранее выделять нужный буфер.
и солнце б утром не вставало, когда бы не было меня
Re[3]: Listener без цикла?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.06.13 13:34
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, Serginio1, Вы писали:


S>>Смотри ассинхронный BeginAccept


AVK>BeginAccept это серверная сторона. А главное — он не принимает данных. Тебе управление вернется сразу после того как accept клиента отработает, а читать все равно надо ручками из NetworkStream.

Ну читать то не проблема. Главное определить когда надо читать. Да поторопился. Есть ассинхронный клиент.
http://www.sql.ru/forum/188228/assinhronnye-sokety-vopros-po-teorii

Правда я сжимаю трафик


public static void WriteCompressedString(NetworkStream стрим, string Value)
        {
            if (Value.Length == 0)
            {
                Write(стрим, false);
                Write(стрим, 0);
                return;
            }


            byte[] result = CurrentEncoder.GetBytes(Value);
            var СжатыеДанные=СжатьДанные(result);
            if (result.Length>СжатыеДанные.Length)
            {
            Write(стрим, true);
            Write(стрим, СжатыеДанные.Length);
            ЗаписатьМассивБайтовВСтрим(стрим,СжатыеДанные);
            }
            else
            {
            Write(стрим, false);
            Write(стрим, result.Length);
            ЗаписатьМассивБайтовВСтрим(стрим,result);
            }
            

        }

и соответственно чтение

public static string ReadString(NetworkStream стрим)
        {
         int РазмерДанных=ReadInt32(стрим);
         if (РазмерДанных == 0) return "";

         return CurrentEncoder.GetString(МассивБайтовИзСтрима(стрим,РазмерДанных));
        }


private static byte[] МассивБайтовИзСтрима(NetworkStream стрим, int размерМассива)
        {
            byte[] result = new byte[размерМассива];
            int количествоСчитанныхСимволов = 0;
            while (размерМассива > количествоСчитанныхСимволов)
            {
                количествоСчитанныхСимволов += стрим.Read(result, количествоСчитанныхСимволов, размерМассива - количествоСчитанныхСимволов);
            }

            return result;
        }

public static string ReadCompressedString(NetworkStream стрим)
        {
            bool ЭтоСжатаяСтрока = ReadBool(стрим);

            if (!ЭтоСжатаяСтрока) return ReadString(стрим);

            int РазмерДанныхДляКоманды = BitConverter.ToInt32(МассивБайтовИзСтрима(стрим, 4), 0);
            byte[] массивДанныхДляКоманды = МассивБайтовИзСтрима(стрим, РазмерДанныхДляКоманды);
            массивДанныхДляКоманды = РасжатьДанные(массивДанныхДляКоманды);
            return CurrentEncoder.GetString(массивДанныхДляКоманды);

        }
и солнце б утром не вставало, когда бы не было меня
Re: Listener без цикла?
От: Danchik Украина  
Дата: 13.06.13 13:43
Оценка: 2 (1)
Здравствуйте, mDmitriy, Вы писали:

D>Доброго всем!


D>Создаю Socket, подключаю его к удаленному серверу, создаю NetworkStream для этого сокета.

D>Далее в отдельном потоке в цикле проверяю оный NetworkStream, нельзя ли из него что-нибудь полезного от сервера прочесть.
D>Все работает...

D>Вопрос: нет ли в NET готового сетевого слушателя, чтобы работал как Timer — создал, подписался на событие о поступлении инфы, подключился и счастлив?


Может не надо велосипедостроительства?
Тыц:

WCF — http://manjuhpt.wordpress.com/2010/06/25/good-example-for-wcf-nettcpbinding/
Thrift (RPC от Cassandra) — http://habrahabr.ru/post/106839/
ZeroMQ (очень интересный асинхронный транспорт) — http://www.zeromq.org/bindings:clr
Re[7]: Listener без цикла?
От: Аноним  
Дата: 13.06.13 13:49
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Ну, как бы использование блокирующих вызовов в листенере — не самая лучшая практика. Пул потоков ограничен скромной величиной, а его раздувание весьма прожорливо в плане ресурсов, при ее превышении клиентские запросы будут подвисать. Поэтому рекомендуемая практика — использовать IOCP. Или IOCP тоже идиоты придумали и он не нужен?


С ними тоже не все хорошо, как выяснилось http://rsdn.ru/forum/dotnet/5197113.flat
Автор:
Дата: 10.06.13
Re[8]: Listener без цикла?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.06.13 13:50
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>С ними тоже не все хорошо, как выяснилось http://rsdn.ru/forum/dotnet/5197113.flat
Автор:
Дата: 10.06.13


Ты уверен что проблема в BeginSend, а не в твоем коде?
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[9]: Listener без цикла?
От: Аноним  
Дата: 13.06.13 14:02
Оценка: -1
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, <Аноним>, Вы писали:


А>>С ними тоже не все хорошо, как выяснилось http://rsdn.ru/forum/dotnet/5197113.flat
Автор:
Дата: 10.06.13


AVK>Ты уверен что проблема в BeginSend, а не в твоем коде?


Я код привел. Переход на синхронность решил проблему. Поэтому соглашусь с матумбой.
Re[7]: Listener без цикла?
От: Visor2004  
Дата: 13.06.13 14:14
Оценка:
Здравствуйте, mDmitriy, Вы писали:

D>т.е., все тоже самое, только цикл не дергается понапрасну?

да
Помните!!! ваш говнокод кому-то предстоит разгребать.
Re[9]: Listener без цикла?
От: matumba  
Дата: 13.06.13 14:22
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>По причине того, что схемы с выделением потока на каждого клиента крайне скверно масштабируются.


1) Почему сразу масштабирование? Вы знакомы с задачей вопрошающего? Он строит ферму для копии гугла? У него клиентов может быть РАЗ В СЕКУНДУ, зачем ему масштабирование? Кстати, "голая винда"(XP x86) спокойно переваривает 120 клиентов/сек — подумайте, вы сами-то достигали таких нагрузок? (это мы наш тестовый сервер пытались продавить) И всё это было на тривиальных блокирующих сокетах.
2) Повышение нагрузоустойчивости может быть достигнуто не только тупым stateless сервисом, но и обычным балансировщиком — всё зависит от узкого места системы. Только тогда, когда ты ЗНАЕШЬ это место, тогда имеет смысл говорить "это архитектурное решение не подходит".

AVK>Потому что блокирующий Read требует выделения потока на каждый запрос.


Давайте вернёмся к начальной фразе:

Пул потоков ограничен скромной величиной, а его раздувание весьма прожорливо в плане ресурсов, при ее превышении клиентские запросы будут подвисать.


Я вам скажу больше: если не увеличить пул ожидающих соединений(ПОС), клиентам вообще будет даден немедленный отлуп! (unable to connect)
Поэтому я и сказал, что требуется увеличение ПОС — клиенты немного посидят в подвисшем состоянии, но по кр. мере БУДУТ ОБСЛУЖЕНЫ. Это разве плохо? Зато сам код сервера будет надёжным. И только когда выяснится, что ОДНОГО сервера недостаточно, можно уже думать о пулах нитей, балансировке, оптимизации обслуживания, увеличении серверов.

К слову, всеми расхваливаемый nginx — тоже пример, когда корявая внутренняя "однопоточная" модель (не имеющая никакой защиты) прекрасно проявляет себя в скорости соединений. Тут уже вопрос, что вам важнее — "непадучесть" сервиса или скорость.

M>>Блокирующий слушатель или ридер — наипростейший вариант, почему бы не начать с него?


AVK>Потому что проблемы начнутся даже на очень скромной нагрузке.


Ерунда, выше я привёл цифры. Хотите мне показать ваши "нагрузки"?
Re[10]: Listener без цикла?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.06.13 16:35
Оценка:
Здравствуйте, matumba, Вы писали:

M>1) Почему сразу масштабирование? Вы знакомы с задачей вопрошающего?


А ты знаком, что советуешь ему блокирующие методы?


AVK>>Потому что блокирующий Read требует выделения потока на каждый запрос.

M>Давайте вернёмся к начальной фразе:

Давай. К твоей:

Есть старый, добрый, блокирующий Read — как данные придут, ты об этом сразу узнаешь.


M>К слову, всеми расхваливаемый nginx — тоже пример, когда корявая внутренняя "однопоточная" модель (не имеющая никакой защиты) прекрасно проявляет себя в скорости соединений.


nginx крайне скверно проявляет себя в windows версии.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[10]: Listener без цикла?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 13.06.13 16:35
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Я код привел.


Мне, если честно, лень в нем разбираться, где ты там мог накосячить.

А> Переход на синхронность решил проблему. Поэтому соглашусь с матумбой.


В чем?
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
AVK Blog
Re[11]: Listener без цикла?
От: Аноним  
Дата: 13.06.13 17:18
Оценка: :)
Здравствуйте, AndrewVK, Вы писали:

А>>Я код привел.


AVK>Мне, если честно, лень в нем разбираться, где ты там мог накосячить.


Ну там 20 строчек. Плюс его не только вы смотрели. Мне кажется вы мало опыта имеет с IOCP. Поэтому не знаете этих особенностей. Я вот тоже до недавних пор не знал про эту фушку.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.