Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.02.10;
Скачать: CL | DM;

Вниз

Локальный порт для клиента 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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.042 c
14-29018
Cobalt
2003-01-21 21:16
2003.02.10
Delphi<->Kylix3


1-28782
Lexa2003
2003-01-29 23:15
2003.02.10
Как можно узнать, какой выставлен год на компьютере?


1-28832
Макс1
2003-02-02 13:36
2003.02.10
showmessage


1-28872
Weare
2003-01-30 11:16
2003.02.10
Что за фишка, просто глюк какой-то.


3-28606
Я
2003-01-23 08:55
2003.02.10
Просто тема