Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 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
14-29097
Думкин
2003-01-24 06:47
2003.02.10
Ощущения


6-28956
ДенМат
2002-12-18 08:56
2003.02.10
DNS, PROXY


3-28584
Стас
2003-01-21 14:26
2003.02.10
Фигня с TDateTime


7-29122
McAndy
2002-11-22 13:26
2003.02.10
использовние COM-порта под Windows NT


1-28856
Noname2
2003-01-30 11:13
2003.02.10
Метка как объект в run-time





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский