![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
Finalist |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 23.5.2006 Репутация: нет Всего: 1 |
Приветствую всех!
Сейчас использую такую схему приемо-передачи данных клиент-сервер: каждый клиент подключается к серверу дважды.. после рукопожатия отмечает сокеты как приемный и передающий.. в один сокет пишет он серверу, по второму сервер пишет клиенту. таким образом есть возможность серверу быть инициатором команд.. все работает прекрасно, нет никаких проблем. Вчера появился в голове вопрос.. возможно ли сделать такую схему на одном сокете? Не будет ли коллизии при отсылке пакетов от клиента к серверу и наоборот? Накидал два проектика со схемой одного сокета. снифером пытался пронюхать.. есть ошибки приема.. хочу получить подтверждение того что эта схема не работает! В снифере вот такой результат:
|
|||
|
||||
Finalist |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 23.5.2006 Репутация: нет Всего: 1 |
Переписал немного тестовые программки...
отсылаю не просто ААА в одну сторону и ВВВ в другую, а теперь шлю в обе стороны по очереди 111, 222, 333, 444, 555 и так далее... снифаю порт: получаю нормальную очередность, но иногда приходят пустые пакеты.. а иногда два пакета склеены в один. так что, вопрос снят. Если у кого-то есть соображения по этому поводу, прошу говорить! мне эта тема очень интересна и важна.
|
|||
|
||||
1Nikita |
|
|||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 8.11.2008 Репутация: нет Всего: нет |
Я вот думаю, можно ли перекачивать воду по одной трубе в обе стороны одновременно(полный дуплекс)?
|
|||
|
||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Да ладно Вам, сокет изначально дуплексный.
Сокет же потоковый (SOCK_STREAM), так и должно быть. Все так делают, без особых проблем... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
Finalist |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 23.5.2006 Репутация: нет Всего: 1 |
||||
|
||||
1Nikita |
|
|||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 8.11.2008 Репутация: нет Всего: нет |
Полудуплекс или полный дуплекс? Если полный, то каким образом отделить в памяти принятые пакеты от отправляемых? порт то один. |
|||
|
||||
Finalist |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 23.5.2006 Репутация: нет Всего: 1 |
||||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Гм. Есть большое желание отправить книжки читать))) На самом деле так сокеты и планировались - полнодуплексными. Порт один, да, но и сокет один, полнодуплексности это никак не мешает. Просто где-то на транспортном уровне формируются отдельные очереди на приём и передачу. Очередь на приём считывается вызовами recv/recvfrom/read, очередь на передачу формируется вызовами send/sendto/write. И всё это на одном и том же сокете. На канальном уровне уже полнодуплесность может отсутствовать (а может и нет), например, в один и тот же момент времени по кабелям может передаваться только один пакет и только в одну сторону. Но и тогда пакеты передаются с бешеной скоростью, то в одну сторону, то в другую, чем, собственно, и обеспечивается одновременная (с точки зрения приложения) передача данных в обе стороны. Никакого водопровода. Посмотрите на описание функции select (или если дело происходит в рамках WinAPI, то WSAWaitForMultipleEvents). Убедитесь, что функция способна обеспечить (даже асинхронную) обработку данных в обе стороны - на приём и на передачу на одном единственном сокете. Никакого мошенничества ![]() Подводные камни встречаются повсюду, но нужно знать реку/залив/гавань, в которой Вы плаваете. Всё сильно зависит от задачи и используемого API. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
1Nikita |
|
|||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 8.11.2008 Репутация: нет Всего: нет |
Ну вот ты скажи тогда, раз порт один то и приёмник и буфер для отправки находятся по одному адресу в памяти. Нам нужно отправить 10 байт в сеть , мы записываем их в порт (send), и тут же из сети приходят пакет 10 байт и тоже попадает в этот порт и нам нужно их считать (recv). И как отделить мух от котлет? С полудуплексом всё понятно,ибо он переключается с приёма на передачу и обратно (типа радиостанции). Это сообщение отредактировал(а) 1Nikita - 2.8.2013, 20:04 |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Буферы разные. Один - на приём, другой - на передачу. Что здесь непонятного? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
1Nikita |
|
||||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 8.11.2008 Репутация: нет Всего: нет |
Если порт один, то и буфер тоже один,в зависимости от того действия которое происходит. Мы сейчас говорим о сокетах, а не о том как реализуется передача данных на других более низких уровнях. И вопрос, кстати, был о дуплексности сокетов. Каким образом ты запишешь в порт (send) и считаешь (recv) оттуда данные одновременно??? ведь полнодуплексный режим именно так работать должен. Даже если делать через события, то всё равно получается полудуплекс, но не полный. Еще раз привожу пример с трубой, как по одной трубе ты перекачаешь воду в двух направлениях одновременно? Либо нужна вторая труба, а это уже другой сокет, либо по очерёдности качаю то в одну то в другую сторону, а это уже ПОЛУдуплекс. |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Ну вот что за упёртость)))) Почему буфер один??? Что мешает завести два (а то и более) буфера? С пользовательской точки зрения У открываемого сокета создаются два буфера - на приём и передачу. В буфер на приём складываются данные, которые пользовательское приложение отправляет в сеть, эти данные могут быть тотчас отправлены, а могут и с задержкой, а то и не отправлены совсем (сеть перегружена или вообще вышла из строя). В буфер на приём складываются данные, которые приходят из сети, и которые должны быть считаны пользовательским приложением, иначе буфер приёма забьётся, и более туда ничего поместить не получится - пришедшие данные будут потеряны. С помощью вызова setsockopt сокету раздельно можно задать размеры этих двух буферов: SO_RCVBUF - для буфера приёма, SO_SNDBUF - для буфера передачи. Можно изловчиться и на одном и том же порту открыть несколько сокетов, у каждого из которых будут свои буферы приёма-передачи, и они не будут друг другу мешать ни коим образом. С точки зрения ОС Каждый приходящий из сети пакет демультиплексируется до пользовательского сокета и кладётся в его буфер приёма. Каждая порция пользовательских данных из буфера передачи аккуратно завёртывается в пакет, который затем уходит в сеть. Я больше скажу. Реально нет никаких статических буферов, есть очереди буферов (которые позволяют избежать лишнего копирования данных). Почитайте хотя бы про mbuf. И срочно читать Стивенса. Пока не прочтёте, лучше не делайте поспешных выводов. Это сообщение отредактировал(а) feodorv - 3.8.2013, 14:16 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
У одного единственного сокета две трубы, вот так ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
1Nikita |
|
|||
Новичок Профиль Группа: Участник Сообщений: 22 Регистрация: 8.11.2008 Репутация: нет Всего: нет |
Если две трубы то это уже симплект по каждой из них ![]() |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Честно, не математик, и юмора не понял ![]() Ну подумайте сами, какая может быть причина для того, чтобы пользоваться одним единственным буфером со всеми вытекающими отсюда неудобствами? Вон у FILE один единственный буфер, по, вполне, кстати, понятным причинам, так каким же нужно быть осторожным, когда переходишь от чтения к записи или от записи к чтению. А у сокета? Да без проблем:
и все проблемы с полнодуплексностью ложатся на сеть. Удобно же. А сколько бы крику было по разным форумам, если бы буфер был один. Так и вижу темы: "Потеряны пакеты при отправке в сокет???" с однотипными ответами "Так нужно было дождаться полного приёма присылаемых данных, а уж потом туда записывать!" и т.д. Два буфера реализуются легко, поддержки по синхронизации не требуют, схема работы с сокетом сразу упрощается, автоматом получается полнодуплексность. Красота ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
![]() ![]() ![]() |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |