![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Пример port mapping
ZeroXider © (2006-08-07 22:00:00)Здравствуйте.
Нужен работающий пример организации качаственного port mapping'a. Знаю, что в Indy есть подходящий компонент (TIdMappedPortTCP), только вот он отказывается нормально работать со сложным (когда поток данных часто меняет свое направление от клиента-к-серверу) самописным протоколом на базе TCP. Это не из-за моей кривости рук, это действительно так.
Я не прошу делать за меня программу, интересует любая полезная информация по данной теме - порт-маппинг и тунелирование трафика.
Спасибо.
ZeroXider (2006-08-08 13:50:00) [21]
> Сергей М. © (08.08.06 13:35) [7]
а.. теперь понял о каких таймаутах вы говорите - readtimeout, connectiontimeout, о них?
действительно клиентское приложение ждет примерно 5 секунд (по-моему это как раз таймаут по-умолчанию), потом пишет, что сервер (порт-маппер) прервал соединение. Прямое соединение клиента к серверу, без использование порт-маппера, работает давно и отлично.
Т.е. проблема именно с TIdMappedPortTCP, который оказался далеко не "useful in implementing transparentproxy server programs", как это сказано в справке :(
Поэтому и спрашиваю, как грамотно построить нормальный порт-маппер.
Сергей М. (2006-08-08 13:35:00) [22]
> есть способы с этим бороться?
С ними не надо бороться.
Их надо грамотно и эффективно использовать.
Ketmar (2006-08-08 13:33:00) [23]совершенно не понимаю проблемы. даже при использовании блокирующего режима все "напряги" решаются при помощи select().
ZeroXider (2006-08-08 13:23:00) [24]
> Slym © (08.08.06 04:31) [3]
> TIdPortMapper
а эт что за зверь такой? в какой закладке искать?
> Сергей М. © (08.08.06 08:51) [4]
> > ZeroXiderВидимо у тебя проблемы с таймаутами.
а можно тут чуточку поподробнее? есть способы с этим бороться? вроде особых задержек нету..
Сергей М. (2006-08-08 08:51:00) [25]
> ZeroXider
Видимо у тебя проблемы с таймаутами.
Slym (2006-08-08 04:31:00) [26]TIdPortMapper
ZeroXider (2006-08-08 03:50:00) [27]
> Пусик © (07.08.06 22:20) [1]
хех.. за пример конечно благодарен, но интересует не на столько уж простенький порт-маппер...
что если в вашем примере данные нужно будет передать в обратном направлении в произвольный (или не очень) момент времени, например как в случае с FTP или более простым HTTP... весь ваш порт-маппер накроется медным тазиком (
интересует именно минимальный полноценный(прозрачный) порт-маппер. Под полноценным, я имею ввиду такой, который будет корректно работать с любым прикладным протоколом.
Пусик (2006-08-07 22:20:00) [28]Вот простенький пример 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.