Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.12.31;
Скачать: [xml.tar.bz2];

Вниз

Пример port mapping   Найти похожие ветки 

 
ZeroXider   (2006-08-07 22:00) [0]

Здравствуйте.

Нужен работающий пример организации качаственного port mapping"a. Знаю, что в Indy есть подходящий компонент (TIdMappedPortTCP), только вот он отказывается нормально работать со сложным (когда поток данных часто меняет свое направление от клиента-к-серверу) самописным протоколом на базе TCP. Это не из-за моей кривости рук, это действительно так.

Я не прошу делать за меня программу, интересует любая полезная информация по данной теме - порт-маппинг и тунелирование трафика.

Спасибо.


 
Пусик ©   (2006-08-07 22:20) [1]

Вот простенький пример TCP Port-Mapping:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ScktComp, StdCtrls;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   cs: TClientSocket;
   ss: TServerSocket;
   procedure FormCreate(Sender: TObject);
   procedure ssClientConnect(Sender: TObject; Socket: TCustomWinSocket);
   procedure ssClientDisconnect(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
   procedure csRead(Sender: TObject; Socket: TCustomWinSocket);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 ss.Port := 4900;
 ss.Open;
end;

procedure TForm1.ssClientConnect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
 cs.Port := 4899;
 cs.Address := "10.0.0.201";
 Memo1.Lines.Add("Client connect, Address="+Socket.RemoteAddress);
end;

procedure TForm1.ssClientDisconnect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
 Memo1.Lines.Add("Client disconnect, Address="+Socket.RemoteAddress);
 cs.Close;
end;

procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
 s: String;
 Len: Integer;
begin
 if not cs.Active then
 begin
   cs.Open;
   while not cs.Active do Application.ProcessMessages;
 end;

 repeat
   Len := Socket.ReceiveLength;
   Memo1.Lines.Add("ss: Принято байт "+IntToStr(Len));
   if Len=0 then break;
   SetLength(s,Len);
   Socket.ReceiveBuf(s[1],Len);
   cs.Socket.SendBuf(s[1],Len);
 until Len=0;
end;

procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);
var
 s: String;
 Len: Integer;
begin
 repeat
   Len := Socket.ReceiveLength;
   Memo1.Lines.Add("cs: Принято байт "+IntToStr(Len));
   if Len=0 then break;
   SetLength(s,Len);
   Socket.ReceiveBuf(s[1],Len);
   ss.Socket.Connections[0].SendBuf(s[1],Len);
 until Len=0;
end;

end.


 
ZeroXider   (2006-08-08 03:50) [2]


> Пусик ©   (07.08.06 22:20) [1]

хех.. за пример конечно благодарен, но интересует не на столько уж простенький порт-маппер...
что если в вашем примере данные нужно будет передать в обратном направлении в произвольный (или не очень) момент времени, например как в случае с FTP или более простым HTTP... весь ваш порт-маппер накроется медным тазиком (

интересует именно минимальный полноценный (прозрачный) порт-маппер. Под полноценным, я имею ввиду такой, который будет корректно работать с любым прикладным протоколом.


 
Slym ©   (2006-08-08 04:31) [3]

TIdPortMapper


 
Сергей М. ©   (2006-08-08 08:51) [4]


> ZeroXider


Видимо у тебя проблемы с таймаутами.


 
ZeroXider   (2006-08-08 13:23) [5]


> Slym ©   (08.08.06 04:31) [3]
> TIdPortMapper

а эт что за зверь такой? в какой закладке искать?

> Сергей М. ©   (08.08.06 08:51) [4]
> > ZeroXiderВидимо у тебя проблемы с таймаутами.

а можно тут чуточку поподробнее? есть способы с этим бороться? вроде особых задержек нету..


 
Ketmar ©   (2006-08-08 13:33) [6]

совершенно не понимаю проблемы. даже при использовании блокирующего режима все "напряги" решаются при помощи select().


 
Сергей М. ©   (2006-08-08 13:35) [7]


> есть способы с этим бороться?


С ними не надо бороться.
Их надо грамотно и эффективно использовать.


 
ZeroXider   (2006-08-08 13:50) [8]


> Сергей М. ©   (08.08.06 13:35) [7]

а.. теперь понял о каких таймаутах вы говорите - readtimeout, connectiontimeout, о них?
действительно клиентское приложение ждет примерно 5 секунд (по-моему это как раз таймаут по-умолчанию), потом пишет, что сервер (порт-маппер) прервал соединение. Прямое соединение клиента к серверу, без использование порт-маппера, работает давно и отлично.
Т.е. проблема именно с TIdMappedPortTCP, который оказался далеко не "useful in implementing transparent proxy server programs", как это сказано в справке :(

Поэтому и спрашиваю, как грамотно построить нормальный порт-маппер.


 
Сергей М. ©   (2006-08-08 14:01) [9]


> о них?


О них, только не в клиентском приложении, а в самом приложении порт-маппера.


> как грамотно построить нормальный порт-маппер.


Хочешь сказать, что штатный демо-пример с использованием TIdMappedPortTCP не работает как ожидалось ?


 
ZeroXider   (2006-08-08 14:15) [10]


> Сергей М. ©   (08.08.06 14:01) [9]


> О них, только не в клиентском приложении, а в самом приложении
> порт-маппера.

там настройки не трогал, все по-умолчанию.

> Хочешь сказать, что штатный демо-пример с использованием
> TIdMappedPortTCP не работает как ожидалось ?

именно это я и хочу сказать: простейший MappedPort пример под названием Proxy.exe, скомпилированный с исп. Indy 10 не работает.

более того, такая проблема не только у меня http://groups.google.com/group/borland.public.delphi.internet.winsock/browse_thread/thread/7dbe6faad6207817

если бы было все решалось просто, помощи бы не просил.


 
Сергей М. ©   (2006-08-08 14:22) [11]

За Indy10 ничего скуазать не могу.

В 9-ке тот же самый пример работает безукоризненно.


 
ZeroXider   (2006-08-08 14:25) [12]


> Сергей М. ©   (08.08.06 14:22) [11]

я тоже помню, что когда еще пользовался 9 версией - этот пример у меня работал, к сожалению в 10 версии это не так (


 
Сергей М. ©   (2006-08-08 14:47) [13]

Сожалею.


 
Сергей М. ©   (2006-08-08 14:48) [14]

Но на Индейцах свет клином не сошелся)
Любая пара надежно работающих компонентов, реализующих TCP-сервер/клиент, с успехом заменит сабж.


 
ZeroXider   (2006-08-08 15:06) [15]


> Сергей М. ©   (08.08.06 14:48) [14]

дык самое обидное, что только что скачал вполне работоспособный пример, написаный на Билдере с исп. Инди 9. http://www.download.ru/search.ehtml?l=0&t=3&c=0&q=Easy+Port+Mapper Easy Port Mapper. Программа с исходным кодом. А на Indy 10 никак работать не хочет этот компонент.


> Любая пара надежно работающих компонентов, реализующих TCP-
> сервер/клиент, с успехом заменит сабж.

да это понимаю. скорее всего прийдется так и поступить - написать самому. Вот только есть один момент, который мне непонятен, в реализации порт-маппинга.
Как промежуточный сервер узнает о том, что нужно принимать данные или отсылать их и какой их объем? (


 
Сергей М. ©   (2006-08-08 15:13) [16]


> Как промежуточный сервер узнает о том, что нужно принимать
> данные или отсылать их и какой их объем?


Точно так же как и обычный (не порт-маппер) сервер или клиент узнает об этом.

Может быть тебе рано о порт-маппере говорить ?

Ведь порт-маппер - это обычный сервер + куча обычных клиентов ..
Без знания особенностей работы с каждым из них бессмысленно говорить о сквозной логике работы порт-маппера ..


 
ZeroXider   (2006-08-08 15:22) [17]


> Сергей М. ©   (08.08.06 15:13) [16]


> Точно так же как и обычный (не порт-маппер) сервер или клиент
> узнает об этом.

Обычный (не порт-маппер) сервер/клиент принимает/отсылает данные в соответствии с протоколом. А размер данных, опять же, либо фиксирован, либо отсылается непосредственно перед данными, опять же, в соответсвии с прикладным протоколом. Так откуда порт-мапперу знать особенности какого-то там прикладного протокола? имхо там механизм немного другой.


 
Сергей М. ©   (2006-08-08 15:30) [18]


> Обычный (не порт-маппер) сервер/клиент принимает/отсылает
> данные в соответствии с протоколом


Что за глупости ?

Тот же самый TIdMappedPortTCP есть прямой наследник TIdTCPServer.
И с каких же пор, спрашивается, TIdTCPServer работает на уровне какого-то прикладного протокола ?


 
ZeroXider   (2006-08-08 15:37) [19]


> Сергей М. ©   (08.08.06 15:30) [18]

TIdTCPServer принимает/отсылает данные посредством протокола TCP/IP, но вот в какой последовательности и когда принимать и отсылать данные - решает уже прикладной протокол, использующий TCP/IP просто как транспорт.

меня интересут именно то, каким образом порт-маппер, не зная конкретного прикладного протокола, умеет перенаправлять данные.


 
Пусик ©   (2006-08-08 15:57) [20]

> ZeroXider   (08.08.06 03:50) [2]
> > Пусик ©   (07.08.06 22:20) [1]хех.. за пример конечно
> благодарен, но интересует не на столько уж простенький порт-
> маппер... что если в вашем примере данные нужно будет передать
> в обратном направлении в произвольный (или не очень) момент
> времени, например как в случае с FTP или более простым HTTP.
> .. весь ваш порт-маппер накроется медным тазиком (

/I>

Непонятна твоя проблема. Ты имеешь ввиду именно порт-маппер, а не что-то другое?
Приведенный пример именно так и работает - как прозрачный порт-маппер.

Что означает "обратное направление"? Особенно при упоминании http?


 
Reindeer Moss Eater ©   (2006-08-08 16:05) [21]

меня интересут именно то, каким образом порт-маппер, не зная конкретного прикладного протокола, умеет перенаправлять данные.

Не зная прикладного протокола, иначе как работая с буфером длиной в один байт задачу не решить.
Скорее всего.


 
Сергей М. ©   (2006-08-08 16:06) [22]


> ZeroXider   (08.08.06 15:37) [19]



> меня интересут именно то, каким образом порт-маппер, не
> зная конкретного прикладного протокола, умеет перенаправлять
> данные


А ему, мапперу, до лампочки твои прикладные протоколы)
Маппер работает со стримом - получает из вх.стрима некие двоичные данные (неважно какого логического содержимого) и тут же (безо всякой обработки !) перенаправляет полученное в вых.стрим.

А вот прокси - он как раз аккумулирует вх.стрим, анализирует данные во вх.стриме на предмет прикладного протокола и , если надо, формирует данные в соответствии с прикл.протоколом для записи в вых.стрим.

Иными словами, прокси - это "интеллектуальный маппер".


 
ZeroXider   (2006-08-08 16:23) [23]


> Пусик ©   (08.08.06 15:57) [20]

приношу искреннее извинения за [2], ваш пример действительно прекрасно работает... !!! спасибо ещё раз!

> Сергей М. ©   (08.08.06 16:06) [22]

кажется я начинаю понимать, что вы имели ввиду...
правда на блокирующих сокетах задачу решить сложнее.


 
Сергей М. ©   (2006-08-08 16:50) [24]


> на блокирующих сокетах задачу решить сложнее


Ничуть не сложнее чем на неблокирующих.


 
ZeroXider   (2006-08-08 16:52) [25]


> Сергей М. ©   (08.08.06 16:50) [24]

угу, эт тоже уже понял )
если кому интересно - вот простейший работающий пример на Indy.
procedure TfmMain.MappedServExecute(AContext: TIdContext);
var
 OutboundClient: TIdTCPClient;
 FNetData: string;
begin
 //m1.Lines.Add("Connected to mapped serv.");
 OutboundClient := TIdTCPClient.Create;
 try
   OutboundClient.Host := "127.0.0.1";
   OutboundClient.Port := 5050;
   //OutboundClient.ConnectTimeout := 5000;
   //OutboundClient.ReadTimeout := 5000;
   OutboundClient.Connect;
   while AContext.Connection.Connected do
   begin
     AContext.Connection.IOHandler.CheckForDataOnSource;
     FNetData := AContext.Connection.IOHandler.InputBufferAsString;
     if Length(FNetData) > 0 then
     begin
       OutboundClient.IOHandler.Write(FNetData);
     end;
     OutboundClient.IOHandler.CheckForDataOnSource;
     FNetData := OutboundClient.IOHandler.InputBufferAsString;
     if Length(FNetData) > 0 then
     begin
       AContext.Connection.IOHandler.Write(FNetData);
     end;
   end;
 finally
   OutboundClient.Free;
 end;
end;


спасибо всем за помощь и терпение.


 
Сергей М. ©   (2006-08-08 17:02) [26]


> ZeroXider   (08.08.06 16:23) [23]


Пример в [1], при всем уважении к коллеге Пусик (С), есть потенциальный источник известных транспортных ошибок и брать его за пример стоит лишь концептуально.


 
Пусик ©   (2006-08-08 17:32) [27]


> Сергей М. ©   (08.08.06 17:02) [26]
> > ZeroXider   (08.08.06 16:23) [23]Пример в [1], при всем
> уважении к коллеге Пусик (С), есть потенциальный источник
> известных транспортных ошибок и брать его за пример стоит
> лишь концептуально.


Полностью поддерживаю;)


 
ZeroXider   (2006-08-08 17:48) [28]


> Сергей М. ©   (08.08.06 17:02) [26]

ну это понятно, что пример чисто демонстрационный, особенно судя по строке
> ss.Socket.Connections[0].SendBuf(s[1],Len);

))
но в любом случае, я в своем проекте не буду использовать TServer/ClientSocket.
будет что-то вроде [25] (по аналогии с TIdMappedPortTCP), кстати работает стабильно вроде, только вот надо CheckForDataOnSource заменить на хотя бы CheckForDataOnSource(1);



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2006.12.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.04 c
2-1165962183
Khabibulin
2006-12-13 01:23
2006.12.31
Календарь


15-1165503464
Kolan
2006-12-07 17:57
2006.12.31
Что делать с паттернами которые реализованны в BDS только для C#?


15-1165867489
Kostafey
2006-12-11 23:04
2006.12.31
Восстановление БД


8-1147104191
Dstr
2006-05-08 20:03
2006.12.31
Stream и звук


3-1161057847
DelphiN!
2006-10-17 08:04
2006.12.31
Помогите написать SQL запрос ...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский