![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
GorbunovDiman |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 3.3.2008 Репутация: нет Всего: нет |
Читая http://www.rsdn.ru/article/unix/sockets.xml я обратил особое внимание на функцию
как я понял в случае неудачной отправки она посылает заново конец сообщения отдельным пакетом. НО как на другом конце определить, что это куски одного и того же сообщения? если при этом на один сокет может приходить инфа с нескольких компов( для udp)? |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
UDP пакеты всегда посылаются целиком.
Тот пример, который Вы привели, относится к TCP. Узел, с которого пришёл UDP-пакет, определяется по IP-адресу источника. Например, функция
возвращает адрес источника в параметре from. Это сообщение отредактировал(а) feodorv - 20.12.2011, 18:43 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
GorbunovDiman |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 3.3.2008 Репутация: нет Всего: нет |
Нет а если я буду так же бить udp пакет (для параллельной отправки через один соккет нескольких сразу (то есть вроде как параллельной по очереди мелкие куски каждого)) есть ли какая нибудь возможность восстановить пакет на другой стороне?
И вот это уже (для tcp) если допустим мне пришло на соккет сообщение. Я его читаю, но во время чтения туда уже приходит следующее сообщение. Есть ли возможность разграничить их в этом случае? Не сольются ли они? |
|||
|
||||
boostcoder |
|
||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
это возможно, если вы напишите свой протокол ;)
например, как вы предполагаете это сделать?
бред какой-то пишите. следующее сообщение встанет в очередь, и вы его прочтете только после того, как прочтете предыдущее. |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Конечно, есть, но только если Вы сами будете следить за порядком UDP-пакетов. А это приводит нас к: Если прямо вот во время чтения, то нет. Если же Ваш процесс занят чем-нибудь, и в это время приходит один пакет, потом другой, то, да, эти два сольются (если, конечно, буфер сокета их вместит). Опять таки, чтобы их разграничить, Вам нужно внести в пакеты дополнительные данные (заголовок типа ид пакета, длина, номер, CRC заголовка и т.д.), то есть реализовать собственный протокол. И уже при чтении следить за границами пакетов. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
GorbunovDiman |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 3.3.2008 Репутация: нет Всего: нет |
Типа если я принимаю дыные с http сервера (незная длину сообщения) мне придётся самому по содержанию ловить точку конца?
|
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Web-сервер вполне может указать длину содержимого в заголовке Content-Length, правда, полагаться на неё не стоит. Если Keep-Alive выключен, то по окончании передачи данных сервер просто прикроет соединение. Пользовательской программой это событие может быть воспринято как FD_CLOSE в виндах или ноль как возвращаемое значение функции чтения из сокета. Если же используются постоянные соединения, то каждый ответ сервера обязан содержать правильный заголовок Content-Length, по которому клиент и определяет границы сообщений (Постоянные соединения (Persistent Connections)). Это опять-таки тонкости протокола HTTP, а не TCP. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
У меня появилось некоторое предположение, что Вы не совсем понимаете, что такое сокет. Грубо говоря, сокет - это сочетание трёх параметров:
Соединение есть некая корреляция двух сокетов (созданных на разных узлах или даже на одном узле). Соединение характеризуется уже пятью параметрами:
я понимаю, что вы сокет себе представляете без номера, типа всё течёт в одну дыру. Нет, не в одну. Клиент работает через вызовы:
Сервер работает через вызовы:
Это сообщение отредактировал(а) feodorv - 22.12.2011, 18:08 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
GorbunovDiman |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 89 Регистрация: 3.3.2008 Репутация: нет Всего: нет |
Спасибо за детальное объяснение.
Я это прекрасно понимаю НО! Это не сколько понимание сокетов, сколько изначально задумавшаяся архетектура проги (Которая частично пересмотрена). Подрозумевалось следующие: Для чтения и записи существуют свои потоки (pthread) Конкретно для чтения: Существует множество в которое записываются функции которые должны быть вызваны на выполнение(в потоке чтения) по приходу на сокет какого либо сообщеняя. проблема как раз в том чтобы разграничить сообщения (пометки о длине в них даже и не предпологаются). Это была некая попытка сделать (СВОЮ! boost не предлагать!) надстройку над стандартными сокетами,отдалённо напоминающую std::cout. Вот конкретный пример(на сокет приходят сообщения не с разных машин а с одной!): сервер посылает сообщение 1 сообщение 2 клиент начинает читать(по каким-то причинам уже когда к ниму пришли оба сообщения) Может ли он их разграничит(там нет инфы о длине)? Из ваших постов стало понятно что нет. А вот (чтобы темы не плодить) : У меня есть (уже хорошо отлаженный модуль : обвязка селекта) ему ставются дискрипторы на слежения и функции обработчики.А он вызывает их когда это нужно. Но меня осенило так как я использую отдельные потоки для чтения и записи то можно сокеты делать и блокирующими. (надобность в модуле как бы отпадает отпадает) Вопрос: если в одном потоке send заблокировал сокет, то может ли в другом потоке проходить операция чтеня.(Попытка сделать максимальную асинхронность) И какие приимущества/недостатки у блокирующих/неблокирующих сокетов? |
||||
|
|||||
feodorv |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Извините, если что не так ![]()
Нет, не может.
Верно ![]()
Может. Всё равно все синхронные вызовы реализованы через асинхронные)))
Гм. Конечно, всё зависит от задачи, которую Вы реализуете. Многие задачи, реализацию которых я видел на асинхронных вызовах, могут быть решены с использованием синхронных сокетов. Однако лично я настолько оценил удобство асинхрона, что про синхронные вызовы просто забыл))) У синхронных сокетов есть одно очевидное преимущество - простота их программирования. Использование асинхронных сокетов требует более тонких подходов. Но со временем к ним привыкаешь и не мыслишь себя без них))) Наверняка меня дополнят, но вот так навскидку я вижу такие преимущества применения асинхронных вызовов:
По поводу полнодуплескного режима обмена (я имею в виду, на пользовательском уровне, конечно). Видите, Вам понадобилось аж 2 потока, чтобы иметь возможность одновременно и писать и читать. Потребуется и дополнительная синхронизация этих потоков, если Ваш сервер делает что-нибудь полезное. А ещё нужен один поток, который будет принимать соединения... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||
|
|||||||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |