Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 857
  • Last Modified:

sending data between tcp connections

Hi,
I would like to get all data from one tcp connection, and send it to another tcp connection.

I'm using indy - and so the connections I talk of are TIdTCPServerConnections.

I've tried the following in the onExecute event:



procedure TForm1.serverExecute(AThread: TIdPeerThread);
var temp: char;
begin
        try
                temp:=aThread.Connection.ReadChar;
                if temp <> null then begin
                                otherConnection.Write(temp);
                        end;
                end;
        except

        end;
end;




But this is very slow.
Questions:
1. Is there a faster way of doing this?
2. Is there a way of copying chunks for data and sending it to the other connection? (ie. not sending char by char)

Thanks in advance,
Fidel.
0
fidel83
Asked:
fidel83
3 Solutions
 
vadim_tiCommented:
you can use Indy's TIdMappedPortTCP component
it make exactly what you want , it is descendant of TIdTCPServer,
and you can see its source.

Another option (not too complicate and sure better from performance point of view)
is to use socket WIN Api functions
0
 
fidel83Author Commented:
Thanks vadim,
TIdMappedPortTCP requires you to specify the hostname and port of the computer you wish to forward traffic to. Unfortunately I cannot do that. The connection is originating from behind a proxy server, and thus we cannot probe into it.

As for the second option, I wouldn't know where to begin,
cheers.
Fidel.
0
 
TheRealLokiSenior DeveloperCommented:
myrecord = packed record
    name: string[30];
    age: integer;
    address: string[64];
end;


        j := Stream.Write(myrecord, sizeof(myrecord));
...
        j := Stream.Read(myrecord, sizeof(myrecord));


you can also send a stream. e.g. to send a file you'd dosomething like this :-


// ***** CLIENT

procedure TForm2.Button1Click(Sender: TObject);

var
      SResponse: String;
      AStream: TFileStream;
begin
      with TCPClient do
      begin
            Connect;
            
            while Connected do
            begin
                  AStream := TFileStream.Create('c:\temp.zip', fmCreate); // ready to receive file
            
                  try
                        // banner means the server thread is running
                        SResponse := UpperCase(ReadLn);
                        if Pos('HELLO', SResponse) = 0 then Break;

                        // request FILE data
                        WriteLn('FILE');

                        {      read all bytes until disconnected
                              no length marker in stream }
                        ReadStream(AStream, -1, True);

                  finally
                        Disconnect;
                        AStream.Free; //closes the file
                  end;
            end;
      end;
end;

// ***** SERVER

procedure TForm1.TCPServerExecute(AThread: TIdPeerThread);
var
      SRequest: String;
      SOutline: String;
      AStream: TFileStream;

const EOL: string = #13#10;

begin
      with AThread.Connection do
      begin
            AThread.Synchronize(IncrConnectionCount);

            WriteLn('Hello');

            try
                  SRequest := UpperCase(ReadLn);

                  if SRequest = 'FILE' then
                  begin
                        AStream := TFileStream.Create('c:\out\file.zip', fmOpenRead);
                        OpenWriteBuffer;
                        WriteStream(AStream);
                        CloseWriteBuffer;

                        AStream.Free;
                  end;

            finally
                  Disconnect;
                  AThread.Synchronize(DecrConnectionCount);

            end;
      end;
end;

'scuse typos :)
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
fidel83Author Commented:
ahh did you read my question? :P
0
 
CesarHdezCommented:
Why don't simply read the whole data on the connection, save it onto a string instead of char and write it into your connection

var
  tempStr: String;
begin
  tempStr := AThread.Connection.ReadLn;
  if tempStr <> '' then
    yourConnection.WriteLn(tempStr);

0
 
TheRealLokiSenior DeveloperCommented:
to make your tcp server just pass through everything as it arrives, you can do

procedure TForm1.TCPServerExecute(AThread: TIdPeerThread);
const
    maxbuffer = 8192;
var
    buffer: array[1..maxbuffer] of byte; // stores incoming data
    bufferlength: integer; // actual size of buffer read from client
     AStream: TFileStream;

const EOL: string = #13#10;

begin
     with AThread.Connection do
     begin
          AThread.Synchronize(IncrConnectionCount);

          while Athread.Connected do // not sure of the property name, check it out first
          try
               bufferlength := ReadBuffer(buffer, maxbuffer);
               if bufferlength > 0 then
                   OtherConnection.Writebuffer(buffer, bufferlength);
          finally
               Disconnect;
               AThread.Synchronize(DecrConnectionCount);
          end; // while lopop means we keep reading and sending until done
     end;
end;

think this is right, i'm doing it from memory (away from delphi atm)
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now