Сокеты. select()

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Ответить
Виталий
новенький
Сообщения: 40
Зарегистрирован: 05.01.2013 22:33:11

Сокеты. select()

Сообщение Виталий »

Всем доброго. Использую чистые сокеты для одного проекта в замен ИНДИ и Синапсу.
Все идет хорошо, но понадобилось использовать функции ioctrlsocket или select для ожидания ответа от сервера.
в лазаре есть стандартный модуль sockets, из которого я использую fpXXX функции, но select() среди них нет.
Неужели мне придется подключать модули винды ради этой функции? Или может быть в лазаре есть заменитель (кроссплатформенный) этой функции?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Есть ещё lnet - небольшая, но шустренькая сетевая библиотека, там в модуле lcommon совершенно точно есть функция fpSelect().
Виталий
новенький
Сообщения: 40
Зарегистрирован: 05.01.2013 22:33:11

Сообщение Виталий »

Нашел файл lnethttpdataprovider.pas
В нем есть ссылка на этот модуль, но самого его нет.
Ладно, все равно под винду пока что пишу, так что ДЛЛины ейные заюзаю, просто странно что нет в лазаре такой полезной фички.
Вопрос тогда ставлю по другому: Чем (кроме lnet) вообще по факту для линукса заменяют эту функцию для ожидания получения запрашиваемых данных?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Lazarus тут совершенно ни при чём, Вы не туда смотрите. ;)
У Вас FPC какой версии? У меня 2.6.2, там в папке lnet всё есть.

А чем ещё заменить - я не знаю, т.к. низкоуровневыми сетевыми приложениями занимался только в качестве примера. В работе использую исключительно классы.
Виталий
новенький
Сообщения: 40
Зарегистрирован: 05.01.2013 22:33:11

Сообщение Виталий »

Аналогично. 262 под виндой. Искал в тотале поиском по подпапкам.
Может просто он не входит в пак для винды?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

lnet - кроссплатформенный.
Однако я, кажется, понял Вашу проблему. :) Видимо в стандартной поставке его просто не компилируют. Скачайте исходник FreePascal, распакуете архив, в исходниках заходите в подкаталог utils\fppkg\lnet\ и самостоятельно его скомпилируйте, а потом поместите откомпилированное в свою папку с FPC, в каталог units\Тип_Вашего_компилятора\. После чего заново перезайдите в Lazarus.
Виталий
новенький
Сообщения: 40
Зарегистрирован: 05.01.2013 22:33:11

Сообщение Виталий »

в стандартной поставке его просто не компилируют

Ага. Ну вопрос собсно решен. Скачивать специально не буду, уж если захочется сильно найду как в Линуксе селект использовать отдельно. Пока для винды кодю можно и winsock поюзать, а там видно будет.
Ну а за "на водку" спасибо 8)
Аватара пользователя
yeger
новенький
Сообщения: 49
Зарегистрирован: 17.03.2011 11:26:34

Сообщение yeger »

Столкнулся с похожей проблемой, т.к. при компиляции под андроид lnet упорно не компилировался, использовал просто чтение без очистки буфера в отдельном потоке (чтоб не тормозить основной поток). Могу приложить вариант реализации, если интересно.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Виталий
У нас в ссылках лежит ссылка на сайт lnet. Там скачивать совсем немного.
Про исходники FreePascal я сказал потому, что сам я регулярно люблю там копаться высматривая что-нибудь полезное или что-нибудь совсем мелкое подправить. :) Думаю Вам там покопаться тоже будет интересно, вдруг Вы найдёте функцию Select() в каком-нибудь системном модуле.
Аватара пользователя
Art!P
новенький
Сообщения: 27
Зарегистрирован: 28.07.2012 14:37:53
Контактная информация:

Сообщение Art!P »

неблокирующие сокеты на никсах?
Тогда нужно прикрутить либу baseunix
макросы FD_ в той же либе, называются fpFD_
select будет fpSelect, вместо ioctrlsocket используется fpfcntl(Sock, F_SetFl, O_NONBLOCK);
брал немного кода, с немного сумасшедшего варианта http://lists.freepascal.org/lists/fpc-pascal/2009-May/021203.html
Только меня смущает то, что перед закрытием сокета нужно перевести его в блок.режим, в коде я не заметил.
Или это важно было только для винды, не помню :roll:
но там получится так
Вкл.

Код: Выделить всё

{$ifdef linux}
arg := fpfcntl( s , F_GETFL );
if arg >= 0 then begin
 arg := arg or O_NONBLOCK;
 fpfcntl( s , F_SETFL , arg );
end;
{$endif}

Выкл.

Код: Выделить всё

fpfcntl( s , F_SETFL , 0 );
closesocket(s);
Ответить