Форум: "Сети";
Текущий архив: 2003.02.10;
Скачать: [xml.tar.bz2];
ВнизЛокальный порт для клиента TCP Найти похожие ветки
← →
Verner (2002-12-16 15:34) [0]Как установить локальный порт(номер сокета) для компонентов TCP клиентов?
Или если кто знает компонент, который это позволяет делать.
← →
Digitman (2002-12-16 15:37) [1]Зачем это может понадобиться ?
← →
Verner (2002-12-16 15:44) [2]Я пишу RemoteShell клиента, у которого для коннекта с сервисом надо устанавливать определенный номер сокета от 515 до 1024.
← →
Digitman (2002-12-16 16:14) [3]
> клиента, у которого для коннекта с сервисом надо устанавливать
> определенный номер сокета от 515 до 1024.
Где это документировано ?
← →
Verner (2002-12-16 16:44) [4]У меня документировано, если не веришь - проверь.
Я реализавал уже клиента на другом языке. Но мне надо на дельфях это сделать.
Я понимаю, что можно работать напрямую с винсоком, но неужели никто до сих пор не сделал компонент с возможностью установки локального порта?
← →
Wonder (2002-12-16 17:05) [5]>Verner
>У меня документировано, если не веришь - проверь.
У тебя - это где? Не верю. Давай проверим. Кидай выдержку сюда или в мыло.
← →
Digitman (2002-12-16 17:19) [6]Зачем твоему TCP/UDP-серверу нужно знать порт клиента ? Объясни вот это.
В момент установления коннекта сервер достоверно знает порт клиента, даже если ты сам этого не знаешь, поскольку явно не устанавливал)
← →
Verner (2002-12-16 17:42) [7]Ну вы блин даете!
Документацию написал я сам, так как ее нет вообще.
Как писал?
Запустил снифер, закапчюрил все пакеты и описал алгоритм.
Привожу текст исходника на си(если это что-то прояснит):
...
if( (errport > 1025) || (errport < 514) )
{
Log( "* Warning: Invalid remote port *" );
delete pr;
continue;
}
Log( format("Client errport = %d", errport) );
client.port(errport);
for(int srcport = 1021; srcport > 514; srcport-- )
{
sock es( sock::tcp );
if( es.bind(inetaddr(ioAddr.hostaddr(),srcport)) )
{
if( es.connect(client) )
{
pr->errSock = es;
break;
}
else
Log( "* Warning: Socket connect error *" );
}
else
{
Log( "* Warning: Socket bind error *" );
}
}
...
Почему бы вам просто не ответить, что с такой ситуацией вы не встречались и не знаете как ее решать?
Вместо этого вы выясняете всякую мелочь, которая к делу не относится. Спрашивается зачем? Разговор поддержать?
>Зачем твоему TCP/UDP-серверу нужно знать порт клиента ?
Клиент мой не коннектится со стандартным сервером, а работает с сервисом RemoteShell, который кроме всего прочего проверяет авторизацию на клиенте с запущенным сервером, для передачи номера порта клиента и имени пользователя. Не я придумал сервис RSH, а этого требует именно он.
← →
Digitman (2002-12-16 17:49) [8]так ты ж это уже делаешь !!
вот же строчка
if( es.bind(inetaddr(ioAddr.hostaddr(),srcport)) )
именно bind() это делает.
bind() - он и в Африке bind()
переведи этот код в Паскаль - и всех делов)
На кой тебе компоненты-то сдались ?
← →
Digitman (2002-12-16 17:54) [9]
> Не я придумал сервис RSH, а этого требует именно он.
Раз требует, значит, это должно быть документировано ! Не тобой, я так полагаю, ибо сервис не ты писал.
Вот и спрашиваю - процитируй строчки из документации на RSH, где такие вот требования выставляются. Или дай ссылку, я сам посмотрю
← →
Verner (2002-12-17 05:41) [10]Дело в том, что документации нет! А требования к определенным портам следуют из исходника на си(см. выше) и я определил это опытным путем. Как я могу предоставить ссылку на источник документации если ее нет??? Так или иначе, например из соображений безопасности или из моих личных причин я хочу реализовать назначение локального порта на клиенте, а не могу! Вопрос именно в этом. В исходнике на си работа идет непосредственно(практически) с винсоком, понятное дело, что я могу это сделать через АПИ в дельфи или на любом другом языке. Делал я это на ассемблере через АПИ, си и бэйсик через компоненты. Теперь вопрос: Почему этого нет в Дельфи в стандартной поставке? Это и был самый главный вопрос. И если нельзя, то как можно решить эту проблему? У меня человек пишет на паскале в дельфи, вот и встал вопрос как это сделать именно там. На других языках он не пишет.
← →
Digitman (2002-12-17 08:29) [11]
> требования к определенным портам следуют из исходника на си
Да откуда он взялся, исходник-то ? Кто его писал ? Ты ?
Ну пусть, предположим, переменная srcport содержит номер лок.порта после успешного bind() и коннект также успешно установлен. Что дальше происходит со значением переменной srcport ? Оно пересылается по сети удаленному хосту для каких-то последующих целей ? Если так , то - зачем ? Удаленный хост не сможет впоследствии выполнить коннект к этому порту, ибо порт занят не серверным (слушающим) гнездом, а клиентским !
> Почему этого нет в Дельфи в стандартной поставке?
Чего нет ? Я не понял. Компонентов, реализующих методы назначения лок.порта для клиентских гнезд ? Так и - правильно что нет ! Потому что это крайне некорректно ! Указанный тобой порт может быть уже занят, а ребинд к занятому порту может повлечь массу проблем вплоть до краха обоих процессов (того, который уже занял ранее этот порт и того, который пытается "отнять" это порт "силой")
> У меня человек пишет на паскале в дельфи, вот и встал вопрос
> как это сделать именно там
Точно тот же алгоритм, как ты привел его на С. Только - в синтаксисе Паскаля. Может еще и портировать сей код (с С на Паскаль) прикажешь за тебя ?)
← →
Verner (2002-12-17 09:27) [12]Я пришел не перепираться сюда, а за помощью.
Так как в Дельфи не пишу.
Похоже ответа не получу никогда...
>Указанный тобой порт может быть уже занят, а ребинд к занятому
порту может повлечь..
Для этого организуется цикл, чтоб не попасть на занятый уже порт.
И обычно автоматически назначаемый порт для клиента ОС выдается больше 1000.
>Точно тот же алгоритм, как ты привел его на С. Только - в синтаксисе Паскаля. Может еще и портировать сей код (с С на Паскаль) прикажешь за тебя ?)
Обьектная модель в Дельфи и Си разная. Как ты предлагаешь перевести код из Си в паскаль?! Это не возможно.
Если только использовать АПИ функции, но я про это уже писал и хотел бы избежать такого решения.
← →
Anatoly Podgoretsky (2002-12-17 09:50) [13]Verner & Digitman ©
Digitman тебе дело говорит, на самом деле кроме того, что он сказал есть еще понятие привелигированные порты, и почти любой файрвол и админ просто не позволит их использовать. Для клиента разрешены порты выше 1024
RSH к сожалению не придерживается данных правил, он действительно требует два коннекта, оба с портами 512-1024, поэтому большинство админов его и не разрешают, так как тяжело обеспечить безопасность сети
Насчет компонентов, почти все компоненты обеспечивают установку этого порта вручную, например TClient/ServerSocket
← →
Anatoly Podgoretsky (2002-12-17 09:51) [14]Wonder © (16.12.02 17:05)
На линуксе (RedHat) - man in.rshd
← →
Anatoly Podgoretsky (2002-12-17 09:58) [15]Не буду говорить про другие реализации и ОС и RFC наверно такого требования нет, это возможно требование отдельного продукта
← →
Digitman (2002-12-17 10:00) [16]
> Обьектная модель в Дельфи и Си разная
Безусловно. Никто не утверждает обратное. Но речь идет не о "внутренностях" объектных моделей той или иной языковой среды, а о наличии в составе Делфи библиотечных классов (для работы с кл.TCP-гнездами) со сходными по логике и функц-ти методами/свойствами (например, наличие аналогичного метода Bind)
Да на здоровье ! Не хочешь WinsockAPI - подключи к ДелфиIDE пакет компонентов Indy и задействуй из него компонент-класс TIdTCPClient. Как помнится, у этого класса есть метод Bind, делающий то что тебе нужно.
> Как ты предлагаешь перевести код из Си в паскаль?! Это не
> возможно.
Ерунда полная. В случае прикладных задач (а не системных, как, например, WDM/SYS-драйвер) все замечательно переводится. Нужно лишь подобрать схожие по интерфейсу и функциональности классы в составе OP-библиотек, если без них никак не обойтись.
Поэтому и рекомендую при портинге конкретно этого кода заменить класс sock на класс TIdTCPClient. Все там есть - и bind и connect и все, что душа пожелает
← →
Digitman (2002-12-17 10:09) [17]Да, вот тут <Anatoly Podgoretsky> верно говорит : можно и TClientSocket задействовать, везо всяких "выкрутасов" с применением Indy ради бинда только.
Я посмотрел сейчас событие TClientSocket.OnConnecting(), в момент его возникновение гнездо уже создано, но connect() еще не вызван. Это означает, что , имея доступным SocketHandle и прототип winsockApi-ф-ции bind(), можно в этом событии выполнить повторный ребинд кл.гнезда к нужному порту, отказавшись от автоматически назначенного порта по-умолчанию.
← →
Verner (2002-12-17 11:09) [18]Anatoly Podgoretsky © (17.12.02 09:50)
> Насчет компонентов, почти все компоненты обеспечивают установку этого порта вручную, например TClient/ServerSocket
Это гдеж такая возможность?
Установить у TClientSocket LocalPort нельзя.
Тольку удаленный порт.
Digitman © (17.12.02 08:29)
>> Почему этого нет в Дельфи в стандартной поставке?
>Чего нет ? Я не понял. Компонентов, реализующих методы >назначения лок.порта для клиентских гнезд ? Так и - правильно >что нет ! Потому что это крайне некорректно !
Наконец нашел что-то похожее на спецификацию привожу ссылку:
http://www.freebsd.org/cgi/man.cgi?query=rshd&apropos=0&sektion=0&manpath=FreeBSD+5.0-current&format=html
← →
Digitman (2002-12-17 13:28) [19]
> Это гдеж такая возможность?
> Установить у TClientSocket LocalPort нельзя.
> Тольку удаленный порт.
Вот ты тут упирал на то, что, мол, можно и на WSAPI написать, но типо лениво)...
Позволь уж усомниться в том, что ты свободно ориентируешься в WSAPI. Ибо заглянув в код компонента TClientSocket (в части момента возбуждения OnConnecting) ты бы быстро сообразил, как можно "приспособить" небостающий бинд к компоненту, если известен и доступен хэндл существующего гнезда)
← →
Anatoly Podgoretsky (2002-12-17 13:40) [20]TClientSocket.Socket.LocalPort это не то?
← →
Digitman (2002-12-17 13:53) [21]
> Anatoly Podgoretsky
Не то. TClientSocket вообще bind() не вызывает. По сути, LocalPort - только для чтения (несмотря на возможность записи св-ва) .. В процессе коннекта гнездо все равно получит первый своб.порт и после коннекта св-во LocalPort лишь покажет, какой порт был выделен гнезду системой. В событии OnConnecting() как раз самое место выполнить недостающий bind() для попытки явной привязки к нужному порту
← →
Verner (2002-12-17 15:01) [22]Ух..
>Позволь уж усомниться в том, что ты свободно ориентируешься в >WSAPI. Ибо заглянув в код компонента TClientSocket (в части >момента возбуждения OnConnecting) ты бы быстро сообразил, как >можно "приспособить" небостающий бинд к компоненту, если >известен и доступен хэндл существующего гнезда)
Причем здесь плохо, хорошо.. Не в этом дело.
Я и просил вас подсказать как это сделать!
В паскале я не разбираюсь, как я могу сообразить как это сделать в компоненте?
Я говорил, что без АПИ не сделать, так это или нет?
← →
Digitman (2002-12-17 15:18) [23]
> В паскале я не разбираюсь
???
зато
> У меня человек пишет на паскале в дельфи
что ж он сам не спрашивает, как сделать ?
> без АПИ не сделать, так это или нет?
В TClientSocket - нет. Но WSAPI-вызовов там будет буквально 2-3 строчки, в событии OnConnecting()
В TIdTCPClient - можно, вероятно, и без WSAPI-вызовов обойтись.
Пробуй метод bind, на то он там и существует.
Если заработает, то - проблема твоя решена.
← →
Anatoly Podgoretsky (2002-12-17 15:48) [24]Digitman © (17.12.02 13:53)
Понял, спасибо
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2003.02.10;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.01 c