Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, mDmitriy, Вы писали: D>>Мой вопрос касался сугубо клиента. AVK>Listener это у тебя клиент?
Ну да... Я в сетях не спец, и, возможно, криво выразился.
Имеется ввиду, что клиент посылает серверу запрос и ждет, что тот ему ответит. А ответ может быть долгим и прерывистым. Поэтому надо слушать сокет и собирать данные.
Здравствуйте, matumba, Вы писали:
M>Здравствуйте, mDmitriy, Вы писали:
D>>А ответ может быть долгим и прерывистым. Поэтому надо слушать сокет и собирать данные.
M>Юзай сокеты, Люк! M>Найди любой удобный враппер (чтобы легче читать строки, например) и будет тебе щщастье.
Спасибо!
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, mDmitriy, Вы писали:
D>>Вопрос: нет ли в NET готового сетевого слушателя, чтобы работал как Timer — создал, подписался на событие о поступлении инфы, подключился и счастлив?
S>http://round-angle-net.blogspot.ru/2010/09/tcpip-c.html S>Смотри ассинхронный BeginAccept
Спасибо! Не по моей теме немножко, но очень хорошая статья.
Здравствуйте, 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>>
Здравствуйте, matumba, Вы писали:
M>Нет, только 37.81%; Есть какие-то возражения?
Ну, как бы использование блокирующих вызовов в листенере — не самая лучшая практика. Пул потоков ограничен скромной величиной, а его раздувание весьма прожорливо в плане ресурсов, при ее превышении клиентские запросы будут подвисать. Поэтому рекомендуемая практика — использовать IOCP. Или IOCP тоже идиоты придумали и он не нужен?
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
Здравствуйте, Serginio1, Вы писали:
S>Смотри ассинхронный BeginAccept
BeginAccept это серверная сторона. А главное — он не принимает данных. Тебе управление вернется сразу после того как accept клиента отработает, а читать все равно надо ручками из NetworkStream.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Ну, как бы использование блокирующих вызовов в листенере — не самая лучшая практика.
По какой причине? Потому что ты начитался тырнетных экспертов? А эти эксперты различают задачи?
AVK> Пул потоков ограничен скромной величиной
Причём тут потоки? Я про пул ожидающих соединения. ВРЕМЕННО можно допустить, чтобы этот пул был заполнен. А уже потоки разберут этот пул для обслуживания.
AVK> Поэтому рекомендуемая практика — использовать IOCP. Или IOCP тоже идиоты придумали и он не нужен?
Зачем заниматься крысиной демагогией? Где-то я говорил про идиотов или IOCP? Хочешь — используй, каждый сам хозяин своих проблем. Блокирующий слушатель или ридер — наипростейший вариант, почему бы не начать с него?
Здравствуйте, matumba, Вы писали:
AVK>>Ну, как бы использование блокирующих вызовов в листенере — не самая лучшая практика. M>По какой причине? Потому что ты начитался тырнетных экспертов?
По причине того, что схемы с выделением потока на каждого клиента крайне скверно масштабируются.
AVK>> Пул потоков ограничен скромной величиной M>Причём тут потоки?
Потому что блокирующий Read требует выделения потока на каждый запрос.
M>Блокирующий слушатель или ридер — наипростейший вариант, почему бы не начать с него?
Потому что проблемы начнутся даже на очень скромной нагрузке.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
Здравствуйте, 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(массивДанныхДляКоманды);
}
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, mDmitriy, Вы писали:
D>Доброго всем!
D>Создаю Socket, подключаю его к удаленному серверу, создаю NetworkStream для этого сокета. D>Далее в отдельном потоке в цикле проверяю оный NetworkStream, нельзя ли из него что-нибудь полезного от сервера прочесть. D>Все работает...
D>Вопрос: нет ли в NET готового сетевого слушателя, чтобы работал как Timer — создал, подписался на событие о поступлении инфы, подключился и счастлив?
Здравствуйте, AndrewVK, Вы писали:
AVK>Ну, как бы использование блокирующих вызовов в листенере — не самая лучшая практика. Пул потоков ограничен скромной величиной, а его раздувание весьма прожорливо в плане ресурсов, при ее превышении клиентские запросы будут подвисать. Поэтому рекомендуемая практика — использовать IOCP. Или IOCP тоже идиоты придумали и он не нужен?
Здравствуйте, AndrewVK, Вы писали:
AVK>По причине того, что схемы с выделением потока на каждого клиента крайне скверно масштабируются.
1) Почему сразу масштабирование? Вы знакомы с задачей вопрошающего? Он строит ферму для копии гугла? У него клиентов может быть РАЗ В СЕКУНДУ, зачем ему масштабирование? Кстати, "голая винда"(XP x86) спокойно переваривает 120 клиентов/сек — подумайте, вы сами-то достигали таких нагрузок? (это мы наш тестовый сервер пытались продавить) И всё это было на тривиальных блокирующих сокетах.
2) Повышение нагрузоустойчивости может быть достигнуто не только тупым stateless сервисом, но и обычным балансировщиком — всё зависит от узкого места системы. Только тогда, когда ты ЗНАЕШЬ это место, тогда имеет смысл говорить "это архитектурное решение не подходит".
AVK>Потому что блокирующий Read требует выделения потока на каждый запрос.
Давайте вернёмся к начальной фразе:
Пул потоков ограничен скромной величиной, а его раздувание весьма прожорливо в плане ресурсов, при ее превышении клиентские запросы будут подвисать.
Я вам скажу больше: если не увеличить пул ожидающих соединений(ПОС), клиентам вообще будет даден немедленный отлуп! (unable to connect)
Поэтому я и сказал, что требуется увеличение ПОС — клиенты немного посидят в подвисшем состоянии, но по кр. мере БУДУТ ОБСЛУЖЕНЫ. Это разве плохо? Зато сам код сервера будет надёжным. И только когда выяснится, что ОДНОГО сервера недостаточно, можно уже думать о пулах нитей, балансировке, оптимизации обслуживания, увеличении серверов.
К слову, всеми расхваливаемый nginx — тоже пример, когда корявая внутренняя "однопоточная" модель (не имеющая никакой защиты) прекрасно проявляет себя в скорости соединений. Тут уже вопрос, что вам важнее — "непадучесть" сервиса или скорость.
M>>Блокирующий слушатель или ридер — наипростейший вариант, почему бы не начать с него?
AVK>Потому что проблемы начнутся даже на очень скромной нагрузке.
Ерунда, выше я привёл цифры. Хотите мне показать ваши "нагрузки"?
Здравствуйте, 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>>
Здравствуйте, AndrewVK, Вы писали:
А>>Я код привел.
AVK>Мне, если честно, лень в нем разбираться, где ты там мог накосячить.
Ну там 20 строчек. Плюс его не только вы смотрели. Мне кажется вы мало опыта имеет с IOCP. Поэтому не знаете этих особенностей. Я вот тоже до недавних пор не знал про эту фушку.