Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

recv() с таймаутом


ProgRAMmer Dimonych ©   (2011-10-30 20:15:00) 

Добрался до знакомства с WinSock. Потребовалось реализовать recv() на блокирующем сокете с таймаутом.

По сути, реализую свой прикладной протокол поверх TCP. Есть клиент, есть сервер. Клиент подключается к серверу, сервер в ответ отправляет сообщение с "приветствием". После этого по тому же соединению продолжается обмен другими сообщениями. Размер сообщений произвольный, в общем случае достаточно большой для того, чтобы однократный recv() не вычитывал их полностью. Заодно было бы интересно предусмотреть вариант, что "в следующих версиях" формат сообщений может изменяться. Весь обмен сообщениями с клиентской стороны инкапсулирован в моей же DLLке.

Соответственно, хочется реализовать recv(), которая бы работала не более заданного промежутка времени и вычитывала либо весь заданный объём данных, либо (если их много) сколько успеет.

1. Гугл предложил вариант с использованием select(). Смущает то, что придётся, кажется, вызывать его в цикле, при этом самостоятельно вычисляя для каждого вызова количество оставшегося времени. Не самое красивое решение, как мне кажется.
2. Крутить цикл без select() до завершения отведённого времени, вызывая recv() с MSG_PEEK - не лезет ни в какие ворота: пустая трата процессорного времени.
3. Создавать отдельные потоки и т.п. выглядит слишком громоздким.

Вопрос: насколько правильно я подхожу к организации взаимодействия и как лучше будет выполнять такое чтение?


ProgRAMmer Dimonych   (2011-11-02 23:05:00) [1]

> [7] Andruk   (02.11.11 20:33)
> Не кэшерно, или мама против? Шуткэ :)
> Сокету точно все равно.

Хотя по-хорошему один раз при создании выставить будет достаточно, наверное.


Andruk   (2011-11-02 20:33:00) [2]


> Есть такое дело. Боюсь, правда, что при каждом чтении изменять
> свойства сокета, не слишком хорошо :(


Не кэшерно, или мама против? Шуткэ :)
Сокету точно все равно.


ProgRAMmer Dimonych   (2011-11-02 14:02:00) [3]

> [5] Andruk   (02.11.11 09:05)
> setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO ....
> Вам в помощь.

Есть такое дело. Боюсь, правда, что при каждом чтении изменять свойства сокета, не слишком хорошо :(


Andruk   (2011-11-02 09:05:00) [4]

setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO ....
Вам в помощь.


Slym   (2011-10-31 05:49:00) [5]

ProgRAMmer Dimonych ©   (30.10.11 20:15)
оответственно, хочется реализовать recv(), которая бы работала не более заданного промежутка времени и вычитывала либо весь заданный объём данных, либо (если их много) сколько успеет.

а зачем? цель этого промежутка времени? если пешеход не успел за 10 сек. перейти дорогу я не виноват?


Сергей М.   (2011-10-30 21:08:00) [6]

можно обойтись и без доп.треда, если отказаться от блок.режима в пользу неблокирующего (возможно с асинхронной нотификацией)


ProgRAMmer Dimonych   (2011-10-30 21:01:00) [7]

> [1] Сергей М. ©   (30.10.11 20:45)
> Блокирующий режим для такой цели явно не годится.

Хм, в общем виде, пожалуй, действительно нехорошо. Будет ли в таком случае хорошей идеей выполнять каждую пару "запрос-ответ" в отдельном потоке, а в вызываемой функции либо дожидаться завершения (если продолжение работы до окончания обмена невозможно), либо возвращать управление?

Речь, кстати, идёт о тонком клиенте.


Сергей М.   (2011-10-30 20:45:00) [8]

Блокирующий режим для такой цели явно не годится.


Наверх

Титульная страница Поиск, карта сайта Написать письмо