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

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

Локальный порт для клиента TCP


Страницы:   1 2

Verner ©   (2002-12-16 15:34:00) 

Как установить локальный порт(номер сокета) для компонентов TCP клиентов?
Или если кто знает компонент, который это позволяет делать.


Anatoly Podgoretsky   (2002-12-17 15:48:00) [1]

Digitman © (17.12.02 13:53)
Понял, спасибо


Digitman   (2002-12-17 15:18:00) [2]


> В паскале я не разбираюсь


???

зато


> У меня человек пишет на паскале в дельфи


что ж он сам не спрашивает, как сделать ?


> без АПИ не сделать, так это или нет?


В TClientSocket - нет. Но WSAPI-вызовов там будет буквально 2-3 строчки, в событии OnConnecting()

В TIdTCPClient - можно, вероятно, и без WSAPI-вызовов обойтись.
Пробуй метод bind, на то он там и существует.
Если заработает, то - проблема твоя решена.


Verner   (2002-12-17 15:01:00) [3]

Ух..

>Позволь уж усомниться в том, что ты свободно ориентируешься в >WSAPI. Ибо заглянув в код компонента TClientSocket (в части >момента возбуждения OnConnecting) ты бы быстро сообразил, как >можно "приспособить" небостающий бинд к компоненту, если >известен и доступен хэндл существующего гнезда)

Причем здесь плохо, хорошо.. Не в этом дело.
Я и просил вас подсказать как это сделать!
В паскале я не разбираюсь, как я могу сообразить как это сделать в компоненте?
Я говорил, что без АПИ не сделать, так это или нет?


Digitman   (2002-12-17 13:53:00) [4]


> Anatoly Podgoretsky


Не то. TClientSocket вообще bind() не вызывает. По сути, LocalPort - только для чтения (несмотря на возможность записи св-ва) .. В процессе коннекта гнездо все равно получит первый своб.порт и после коннекта св-во LocalPort лишь покажет, какой порт был выделен гнезду системой. В событии OnConnecting() как раз самое место выполнить недостающий bind() для попытки явной привязки к нужному порту


Anatoly Podgoretsky   (2002-12-17 13:40:00) [5]

TClientSocket.Socket.LocalPort это не то?


Digitman   (2002-12-17 13:28:00) [6]


> Это гдеж такая возможность?
> Установить у TClientSocket LocalPort нельзя.
> Тольку удаленный порт.


Вот ты тут упирал на то, что, мол, можно и на WSAPI написать, но типо лениво)...

Позволь уж усомниться в том, что ты свободно ориентируешься в WSAPI. Ибо заглянув в код компонента TClientSocket (в части момента возбуждения OnConnecting) ты бы быстро сообразил, как можно "приспособить" небостающий бинд к компоненту, если известен и доступен хэндл существующего гнезда)


Verner   (2002-12-17 11:09:00) [7]

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 10:09:00) [8]

Да, вот тут <Anatoly Podgoretsky> верно говорит : можно и TClientSocket задействовать, везо всяких "выкрутасов" с применением Indy ради бинда только.

Я посмотрел сейчас событие TClientSocket.OnConnecting(), в момент его возникновение гнездо уже создано, но connect() еще не вызван. Это означает, что , имея доступным SocketHandle и прототип winsockApi-ф-ции bind(), можно в этом событии выполнить повторный ребинд кл.гнезда к нужному порту, отказавшись от автоматически назначенного порта по-умолчанию.


Digitman   (2002-12-17 10:00:00) [9]


> Обьектная модель в Дельфи и Си разная


Безусловно. Никто не утверждает обратное. Но речь идет не о "внутренностях" объектных моделей той или иной языковой среды, а о наличии в составе Делфи библиотечных классов (для работы с кл.TCP-гнездами) со сходными по логике и функц-ти методами/свойствами (например, наличие аналогичного метода Bind)

Да на здоровье ! Не хочешь WinsockAPI - подключи к ДелфиIDE пакет компонентов Indy и задействуй из него компонент-класс TIdTCPClient. Как помнится, у этого класса есть метод Bind, делающий то что тебе нужно.


> Как ты предлагаешь перевести код из Си в паскаль?! Это не
> возможно.


Ерунда полная. В случае прикладных задач (а не системных, как, например, WDM/SYS-драйвер) все замечательно переводится. Нужно лишь подобрать схожие по интерфейсу и функциональности классы в составе OP-библиотек, если без них никак не обойтись.
Поэтому и рекомендую при портинге конкретно этого кода заменить класс sock на класс TIdTCPClient. Все там есть - и bind и connect и все, что душа пожелает


Anatoly Podgoretsky   (2002-12-17 09:58:00) [10]

Не буду говорить про другие реализации и ОС и RFC наверно такого требования нет, это возможно требование отдельного продукта


Anatoly Podgoretsky   (2002-12-17 09:51:00) [11]

Wonder © (16.12.02 17:05)
На линуксе (RedHat) - man in.rshd


Anatoly Podgoretsky   (2002-12-17 09:50:00) [12]

Verner & Digitman ©
Digitman тебе дело говорит, на самом деле кроме того, что он сказал есть еще понятие привелигированные порты, и почти любой файрвол и админ просто не позволит их использовать. Для клиента разрешены порты выше 1024

RSH к сожалению не придерживается данных правил, он действительно требует два коннекта, оба с портами 512-1024, поэтому большинство админов его и не разрешают, так как тяжело обеспечить безопасность сети

Насчет компонентов, почти все компоненты обеспечивают установку этого порта вручную, например TClient/ServerSocket


Verner   (2002-12-17 09:27:00) [13]

Я пришел не перепираться сюда, а за помощью.
Так как в Дельфи не пишу.
Похоже ответа не получу никогда...

>Указанный тобой порт может быть уже занят, а ребинд к занятому
порту может повлечь..

Для этого организуется цикл, чтоб не попасть на занятый уже порт.
И обычно автоматически назначаемый порт для клиента ОС выдается больше 1000.

>Точно тот же алгоритм, как ты привел его на С. Только - в синтаксисе Паскаля. Может еще и портировать сей код (с С на Паскаль) прикажешь за тебя ?)

Обьектная модель в Дельфи и Си разная. Как ты предлагаешь перевести код из Си в паскаль?! Это не возможно.
Если только использовать АПИ функции, но я про это уже писал и хотел бы избежать такого решения.


Digitman   (2002-12-17 08:29:00) [14]


> требования к определенным портам следуют из исходника на си


Да откуда он взялся, исходник-то ? Кто его писал ? Ты ?

Ну пусть, предположим, переменная srcport содержит номер лок.порта после успешного bind() и коннект также успешно установлен. Что дальше происходит со значением переменной srcport ? Оно пересылается по сети удаленному хосту для каких-то последующих целей ? Если так , то - зачем ? Удаленный хост не сможет впоследствии выполнить коннект к этому порту, ибо порт занят не серверным (слушающим) гнездом, а клиентским !


> Почему этого нет в Дельфи в стандартной поставке?


Чего нет ? Я не понял. Компонентов, реализующих методы назначения лок.порта для клиентских гнезд ? Так и - правильно что нет ! Потому что это крайне некорректно ! Указанный тобой порт может быть уже занят, а ребинд к занятому порту может повлечь массу проблем вплоть до краха обоих процессов (того, который уже занял ранее этот порт и того, который пытается "отнять" это порт "силой")


> У меня человек пишет на паскале в дельфи, вот и встал вопрос
> как это сделать именно там


Точно тот же алгоритм, как ты привел его на С. Только - в синтаксисе Паскаля. Может еще и портировать сей код (с С на Паскаль) прикажешь за тебя ?)


Verner   (2002-12-17 05:41:00) [15]

Дело в том, что документации нет! А требования к определенным портам следуют из исходника на си(см. выше) и я определил это опытным путем. Как я могу предоставить ссылку на источник документации если ее нет??? Так или иначе, например из соображений безопасности или из моих личных причин я хочу реализовать назначение локального порта на клиенте, а не могу! Вопрос именно в этом. В исходнике на си работа идет непосредственно(практически) с винсоком, понятное дело, что я могу это сделать через АПИ в дельфи или на любом другом языке. Делал я это на ассемблере через АПИ, си и бэйсик через компоненты. Теперь вопрос: Почему этого нет в Дельфи в стандартной поставке? Это и был самый главный вопрос. И если нельзя, то как можно решить эту проблему? У меня человек пишет на паскале в дельфи, вот и встал вопрос как это сделать именно там. На других языках он не пишет.


Digitman   (2002-12-16 17:54:00) [16]


> Не я придумал сервис RSH, а этого требует именно он.


Раз требует, значит, это должно быть документировано ! Не тобой, я так полагаю, ибо сервис не ты писал.

Вот и спрашиваю - процитируй строчки из документации на RSH, где такие вот требования выставляются. Или дай ссылку, я сам посмотрю


Digitman   (2002-12-16 17:49:00) [17]

так ты ж это уже делаешь !!

вот же строчка

if( es.bind(inetaddr(ioAddr.hostaddr(),srcport)) )

именно bind() это делает.
bind() - он и в Африке bind()

переведи этот код в Паскаль - и всех делов)

На кой тебе компоненты-то сдались ?


Verner   (2002-12-16 17:42:00) [18]

Ну вы блин даете!
Документацию написал я сам, так как ее нет вообще.
Как писал?
Запустил снифер, закапчюрил все пакеты и описал алгоритм.

Привожу текст исходника на си(если это что-то прояснит):
...
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:19:00) [19]

Зачем твоему TCP/UDP-серверу нужно знать порт клиента ? Объясни вот это.
В момент установления коннекта сервер достоверно знает порт клиента, даже если ты сам этого не знаешь, поскольку явно не устанавливал)


Wonder   (2002-12-16 17:05:00) [20]

>Verner
>У меня документировано, если не веришь - проверь.

У тебя - это где? Не верю. Давай проверим. Кидай выдержку сюда или в мыло.


Страницы:   1 2

Наверх

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