Форум: "Сети";
Текущий архив: 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.047 c