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

Вниз

Пример 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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.044 c
11-1142536671
Lakearo
2006-03-16 22:17
2006.12.31
Прозрачный TextOut


2-1165750746
arturich
2006-12-10 14:39
2006.12.31
TWebBrowser


15-1165855670
Гоблин
2006-12-11 19:47
2006.12.31
MSSQL - посоветуйте книжку


15-1165502145
SkySpeed
2006-12-07 17:35
2006.12.31
HELP! ПК тупо зависает без причины, приходится перезагружать.....


2-1166105483
Dfe
2006-12-14 17:11
2006.12.31
Int64