Столкнулся со следующей проблемой. Написал простейший клиент-сервер на сокетах и на пайпах. Все отлично работает, но не совсем понятен следующий момент:
пересылаю по сокетам 1Мб за 1цикл ~16мс
пересылаю по сокетам 1Кб за 1000 циклов ~300мс
это localhost. по локалке до нескольких минут может передаваться.., про инет можно догадаться..
включал\отключал TCP_NODELAY, не помогло.
сокет создается 1 раз и потом в цикле идут send\recv
на пайпах: 0 и 30 мс соответственно, причем по сети не намного медленнее..
Здравствуйте, Аноним, Вы писали:
А>Столкнулся со следующей проблемой. Написал простейший клиент-сервер на сокетах и на пайпах. Все отлично работает, но не совсем понятен следующий момент:
А>пересылаю по сокетам 1Мб за 1цикл ~16мс А>пересылаю по сокетам 1Кб за 1000 циклов ~300мс А>это localhost. по локалке до нескольких минут может передаваться.., про инет можно догадаться.. А>включал\отключал TCP_NODELAY, не помогло. А>сокет создается 1 раз и потом в цикле идут send\recv
А>на пайпах: 0 и 30 мс соответственно, причем по сети не намного медленнее..
А>В чем проблема?
Код покажи
Re[2]: Сокеты vs Пайпы
От:
Аноним
Дата:
22.08.07 05:49
Оценка:
Здравствуйте, gandjustas, Вы писали:
G>Код покажи
Сервер и клиент работают с сокетами через один и тот же класс.
Метод инициализации сокетов одинаковый для клиента и сервера:
1. Если при измерениях получены "волшебные" числа — 0мс, 15мс, 30мс — это свидетельства потери квантов времени исполняющим потоком. Квант у нас обычно 10 или 15 мс ( на десктопах )
2. Разное поведение свидетельствует о разной логике интерфейса драйвер-пользовательское приложение. Возможны следующие модели:
— синхронный драйвер — управление не будет возвращено до тех пор пока драйвер реально не обработает запрос ( возможно, просто скопирует пользовательский буфер ). Допустим пользовательское приложение в цикле обращается к драйверу. В таком случае за отведенный квант времени пользовательское приложение успеет выполнить фиксированное количество запросов и соответственно передать фиксированный объем данных
— асинхронный драйвер — если запрос не может быть обработан немедленно ( например для TCP/IP драйвера ситуация когда буфер передачи уже заполнен ), управление возвращается пользовательскому приложению со статусом PENDING, буфера блокируются в памяти ( если только ввод/ввод не буферизированный ). Когда операция оканчивается — система уведомляет пользовательское приложение об этом. И вот тут возможны два варианта поведения приложения:
а) Приложение работает с драйвером как с синхронным. Вот тут важно! В этом случае система сама организует синхронный режим — переходит в режим ожидания завершения операции. А каждый переход в режим ожидания приводит к перепланировке задач и потери кванта времени. Т.е если ваш поток в самом начале своего кванта выполнения выполнит синхронную операцию, то в лучшем случае он получит управления, когда операция будет выполнена ( если нет активных задач ), в худшем — потеряет несколько квантов времени ( на серверных платформах квант может быть и 50мс, так что терять их довольно накладно ). В результате в передачи могут быть внушительные дыры.
б) Приложение работает с драйвером как с асинхронным. В Вашем случае это могло бы выглядить так: вызов в цикле операции WSASend даже если она вернула код ошибки ( конечно, нужно убедиться, что код ошибки WSA_IO_PENDING ), а потом ожидание окончания всех операций. В этом случае можно получить максимальную производительность.
Для сокетов результат очевиден. send и recv тяжелые операции из-за копирования данных в ядро и назад, recv чаще всего вызывает переключение потока.
При передачи по сети без TCPNODELAY результат вообще будет ужасным.
А вот с пайпами интереснее. Возможно пайпы на локальном компьютере вообще не используют сокеты. Хотя хотелось бы увидеть код с пайпами.
Re: Сокеты vs Пайпы
От:
Аноним
Дата:
23.08.07 06:57
Оценка:
А>В чем проблема?
Я по неопытности думал что сокеты это достаточно просто... оказалось все совсем наоборот... Тогда подскажите, раз такие грабли с сокетами, и они появились не сегодня ( и грабли и сокеты , может быть есть относительно доступные библиотеки в которых учтены все эти тонкости и на которых можно организовать наиболее эффективную работу сервера и клиента? Первоначально предпологалось выявить наиболее производительный способ связи между сервером и клиентом в локальной сети. Пайпы взяли чисто для сравнения, думая что сокеты это есть круто, но есть ощущение что это не совсем так..
А>Пайпы взяли чисто для сравнения, думая что сокеты это есть круто, но есть ощущение что это не совсем так..
Это только ощущение. Сокеты — это всего лишь интерфейс к транспортному драйверу. Сам транспортный драйвер, будте уверены, работает очень быстро и эффективно. Интерфейс тоже не самый медленный — например, FTP клиент может запросто скачивать файл со скоростью в 80% от пропускной способности сети. По поводу пайпов — они по разному реализованы для локального и для сетевого варианта использования. Если идет локальный обмен, используется ( вроде ) LPC, что в конце концов сводится просто к разделяемой области памяти. При работе через сеть используется все тот же транспортный драйвер. Вообще, если сеть 100МБ, то основное ограничение в скорости — пропускная способность а не тонкости устройства драйверов.
Здравствуйте, Аноним, Вы писали:
А>Первоначально предпологалось выявить наиболее производительный способ связи между сервером и клиентом в локальной сети.
Здравствуйте, Аноним, Вы писали:
А>может быть есть относительно доступные библиотеки в которых учтены все эти тонкости и на которых можно организовать наиболее эффективную работу сервера и клиента?
Есть то они есть, но для понимания процесса неплохо бы и литературку какую полистать. Например: A. Jones, J. Ohlund, "Network Programming for Windows" и Й. Снейдер, "Эффективное программирование TCP/IP". Т.к. ссылки на книги здесь не приветствуются, то скажу, что у меня на сайте их нет
Re[4]: Сокеты vs Пайпы
От:
Аноним
Дата:
23.08.07 11:50
Оценка:
G>А вот с пайпами интереснее. Возможно пайпы на локальном компьютере вообще не используют сокеты. Хотя хотелось бы увидеть код с пайпами.
Не испульзуют. Локально пайпы работают сразу через shared memory и потому локально конечно на порядок шустрее сокетов.
G>>Локально пайпы работают сразу через shared memory и потому локально конечно на порядок шустрее сокетов.
Это кстати не факт абсолютно. Локальные соединения создаются без использования на самом деле TCP стека и передача блока данных в наилучшем случае будет сводиться к одному копированию — из пользовательского буфера передающего приложения в буфер принимающего. И проигрыша на порядок по сравнению с пайпами быть не должно. При оптимальном использовании совкетов производительность должна быть примерно равна.
Да пребудет с тобою сила
Re[3]: Сокеты vs Пайпы
От:
Аноним
Дата:
23.08.07 13:59
Оценка:
Здравствуйте, TarasCo, Вы писали:
А>>Пайпы взяли чисто для сравнения, думая что сокеты это есть круто, но есть ощущение что это не совсем так..
TC>Это только ощущение. Сокеты — это всего лишь интерфейс к транспортному драйверу. Сам транспортный драйвер, будте уверены, работает очень быстро и эффективно. Интерфейс тоже не самый медленный — например, FTP клиент может запросто скачивать файл со скоростью в 80% от пропускной способности сети.
Да, передавал 5мегов. send отработал мгновенно, причем за один раз. Качал через интернет. Канал был загружен на всю катушку 500кб\сек. Смотрел через файрвол, он показывал какое приложение с какой скоростью принимает\отсылает данные. Как только стал отсылать мелочь по 100 байт. сразу скорость упала до 0.5 кб на прием и отправку. т.е. 1 цикл: отправил 5мб принял 4б выполнился за ~200мс через интернет. 1000 циклов: отправил 100 байт принял 4 байта выполнились за 7 минут. реально передано 100кб... т.е тупой send\receive непрокатывает для мелких запросов ответов. надо обязательно делать асинхронную обвеску для них...
Re[6]: Сокеты vs Пайпы
От:
Аноним
Дата:
23.08.07 14:08
Оценка:
TC>Это кстати не факт абсолютно. Локальные соединения создаются без использования на самом деле TCP стека и передача блока данных в наилучшем случае будет сводиться к одному копированию — из пользовательского буфера передающего приложения в буфер принимающего. И проигрыша на порядок по сравнению с пайпами быть не должно. При оптимальном использовании совкетов производительность должна быть примерно равна.
Не следует забывать еще и про пачку LSP через которые прогоняется трафик. Мало ли что там..
Re[3]: Сокеты vs Пайпы
От:
Аноним
Дата:
23.08.07 14:08
Оценка:
Здравствуйте, Michael Chelnokov, Вы писали:
MC>Здравствуйте, Аноним, Вы писали:
А>>Первоначально предпологалось выявить наиболее производительный способ связи между сервером и клиентом в локальной сети.
MC>Для чего?
Как и говорил, для того чтобы определить, какой наиболее эффективный способ (по скорости двунаправленной передачи данных, независимо от размера передаваемых пакетов) связать в локальной сети два приложения. А так же связать 2 приложения запущенных на одной машине. В этом случае наверное разделяемая память вне конкуренции.
Вопрос возник когда по сокетам, в приведенном примере, стал передавать мелкие пакеты. Передавая большие объемы по сокетам и пайпам имели примерно одинаковую производительность на локальной машине ( с приемуществом пайпов ). Но при массовой пересылке мелких пакетов сокеты стали в 10 раз медленнее пайпов...
А>Не следует забывать еще и про пачку LSP через которые прогоняется трафик. Мало ли что там..
Ну, во-первых, на чистой системе их нет. Во-вторых, никто не мешает приложению явно указывать SPI провайдера и тем самым избегать фильтрации.
Да пребудет с тобою сила
Re[3]: Сокеты vs Пайпы
От:
Аноним
Дата:
23.08.07 14:14
Оценка:
Здравствуйте, Gomes, Вы писали:
G>Здравствуйте, Аноним, Вы писали:
А>>может быть есть относительно доступные библиотеки в которых учтены все эти тонкости и на которых можно организовать наиболее эффективную работу сервера и клиента? G>Есть то они есть, но для понимания процесса неплохо бы и литературку какую полистать. Например: A. Jones, J. Ohlund, "Network Programming for Windows" и Й. Снейдер, "Эффективное программирование TCP/IP". Т.к. ссылки на книги здесь не приветствуются, то скажу, что у меня на сайте их нет
Жаль что нет ссылочки Теперь понятно что придется вникать в тонкости сокетов. Я как-то видел две тоненькие книженции 1 и 2-ю части про какую-то библиотеку для разработки клиент-серверных приложений, основанную на сокетах. Но тогда это мне совсем небыло нужно.. Может кто поймет про что я говорю. Может подскажет имеет смысл ее использовать ?
Re[4]: Сокеты vs Пайпы
От:
Аноним
Дата:
23.08.07 14:18
Оценка:
А>Да, передавал 5мегов. send отработал мгновенно, причем за один раз. Качал через интернет. Канал был загружен на всю катушку 500кб\сек. Смотрел через файрвол, он показывал какое приложение с какой скоростью принимает\отсылает данные. Как только стал отсылать мелочь по 100 байт. сразу скорость упала до 0.5 кб на прием и отправку. т.е. 1 цикл: отправил 5мб принял 4б выполнился за ~200мс через интернет. 1000 циклов: отправил 100 байт принял 4 байта выполнились за 7 минут. реально передано 100кб... т.е тупой send\receive непрокатывает для мелких запросов ответов. надо обязательно делать асинхронную обвеску для них...
Странно. А TCPNODELAY случайно не был включен? Изза него как раз такое может быть.
Здравствуйте, Аноним, Вы писали:
А>>Да, передавал 5мегов. send отработал мгновенно, причем за один раз. Качал через интернет. Канал был загружен на всю катушку 500кб\сек. Смотрел через файрвол, он показывал какое приложение с какой скоростью принимает\отсылает данные. Как только стал отсылать мелочь по 100 байт. сразу скорость упала до 0.5 кб на прием и отправку. т.е. 1 цикл: отправил 5мб принял 4б выполнился за ~200мс через интернет. 1000 циклов: отправил 100 байт принял 4 байта выполнились за 7 минут. реально передано 100кб... т.е тупой send\receive непрокатывает для мелких запросов ответов. надо обязательно делать асинхронную обвеску для них...
А>Странно. А TCPNODELAY случайно не был включен? Изза него как раз такое может быть.
Здравствуйте, Michael Chelnokov, Вы писали:
MC>Здравствуйте, Аноним, Вы писали:
А>>Как и говорил, для того чтобы определить, ...
MC>Ради спортивного интереса что ли?
Ну можно и так сказать. Точнее по незнанию что именно и как применить для звязи двух приложений в локалке...
Re[6]: Сокеты vs Пайпы
От:
Аноним
Дата:
23.08.07 14:31
Оценка:
FM>Непомогло никак.
Прочитайте плз еще раз что я написад. Включение TCPNODELAY _значительно_замедляет_ передачу поткоа мелкими фрагментами
Здравствуйте, Аноним, Вы писали:
А>Я как-то видел две тоненькие книженции 1 и 2-ю части про какую-то библиотеку для разработки клиент-серверных приложений, основанную на сокетах.
Здравствуйте, Аноним, Вы писали:
А>>В чем проблема? А>Я по неопытности думал что сокеты это достаточно просто... оказалось все совсем наоборот... Тогда подскажите, раз такие грабли с сокетами, и они появились не сегодня ( и грабли и сокеты , может быть есть относительно доступные библиотеки в которых учтены все эти тонкости и на которых можно организовать наиболее эффективную работу сервера и клиента? Первоначально предпологалось выявить наиболее производительный способ связи между сервером и клиентом в локальной сети. Пайпы взяли чисто для сравнения, думая что сокеты это есть круто, но есть ощущение что это не совсем так..
Если необходимо передавать маленькими порциями в режиме вопрос-ответ в пределах локальной сети, то лучше использовать UDP.
Если не секрет что должны клиент и сервер передавать друг другу?
Здравствуйте, Gomes, Вы писали:
G>Здравствуйте, Аноним, Вы писали:
А>>Я как-то видел две тоненькие книженции 1 и 2-ю части про какую-то библиотеку для разработки клиент-серверных приложений, основанную на сокетах.
G>ACE?
Она самая. Спасибо.
Здравствуйте, Gomes, Вы писали:
G>Здравствуйте, freelancer.malma, Вы писали:
FM>>Она самая. Спасибо.
G>Но использовать какие-либо библиотеки только для связи _двух_ машин в локалке как-то не разумно. Тут элементарная задача на голых сокетах решаемая.
Вот и я так же поначалу думал...и столкнулся с вышеуказанными проблемами. Исходники есть, можете посмотреть..
Я так пока думаю в следующих направлениях попробовать действовать:
1. использовать UDP протокол.
2. Использовать более сложную асинхронную обвязку.
3. Использовать 2 соединения: 1 на прием , 1 на отправку.
Здравствуйте, freelancer.malma, Вы писали:
FM>Вот и я так же поначалу думал...и столкнулся с вышеуказанными проблемами. Исходники есть, можете посмотреть..
Да нет никаких проблем. В зависимости от потребностей надо поиграться с размером буферов и форматом протокола. Мельком глянув код я заметил что сначала передается размер, а потом сами данные. Попробуй слать их вместе. Быстрее ТСР на голых сокетах (даже синхронных) для этой задачи ничего не придумаешь.
Здравствуйте, Gomes, Вы писали:
G>Здравствуйте, freelancer.malma, Вы писали:
FM>>Вот и я так же поначалу думал...и столкнулся с вышеуказанными проблемами. Исходники есть, можете посмотреть.. G>Да нет никаких проблем. В зависимости от потребностей надо поиграться с размером буферов и форматом протокола. Мельком глянув код я заметил что сначала передается размер, а потом сами данные. Попробуй слать их вместе. Быстрее ТСР на голых сокетах (даже синхронных) для этой задачи ничего не придумаешь.
Да, действительно немного помогло:
-------------- Режим клиента ---------------
Режим сокетов:
Передано 1000 блоков данных по 100 байт за 343 мс
Передано 1000 блоков данных по 1000 байт за 344 мс
Режим pipes:
Передано 1000 блоков данных по 100 байт за 15 мс
Передано 1000 блоков данных по 1000 байт за 31 мс
------------Client shutdown------------
Это после того как убрал один send\recv
-------------- Режим клиента ---------------
Режим сокетов:
Передано 1000 блоков данных по 100 байт за 188 мс
Передано 1000 блоков данных по 1000 байт за 187 мс
Режим pipes:
Передано 1000 блоков данных по 100 байт за 15 мс
Передано 1000 блоков данных по 1000 байт за 31 мс
------------Client shutdown------------
Здравствуйте, freelancer.malma, Вы писали:
FM>Здравствуйте, Gomes, Вы писали:
G>>Здравствуйте, freelancer.malma, Вы писали:
FM>>>Вот и я так же поначалу думал...и столкнулся с вышеуказанными проблемами. Исходники есть, можете посмотреть.. G>>Да нет никаких проблем. В зависимости от потребностей надо поиграться с размером буферов и форматом протокола. Мельком глянув код я заметил что сначала передается размер, а потом сами данные. Попробуй слать их вместе. Быстрее ТСР на голых сокетах (даже синхронных) для этой задачи ничего не придумаешь. FM>Да, действительно немного помогло:
FM>-------------- Режим клиента --------------- FM>Режим сокетов: FM>Передано 1000 блоков данных по 100 байт за 343 мс FM>Передано 1000 блоков данных по 1000 байт за 344 мс FM>Режим pipes: FM>Передано 1000 блоков данных по 100 байт за 15 мс FM>Передано 1000 блоков данных по 1000 байт за 31 мс FM>------------Client shutdown------------
FM>Это после того как убрал один send\recv FM>-------------- Режим клиента --------------- FM>Режим сокетов: FM>Передано 1000 блоков данных по 100 байт за 188 мс FM>Передано 1000 блоков данных по 1000 байт за 187 мс FM>Режим pipes: FM>Передано 1000 блоков данных по 100 байт за 15 мс FM>Передано 1000 блоков данных по 1000 байт за 31 мс FM>------------Client shutdown------------
FM>Но разница с пайпами все равно значительная..