Solved

send receive TMemorystream over UDP

Posted on 2008-10-21
8
1,723 Views
Last Modified: 2013-11-23
hi all,

i trying like to porting my software that was compiled by delphi 6 to delphi 2007;
unfortunately, i can't found the subtitute for nmUDP (netmaster) component which have methode :
readstream, and sendstream  of Tmemorystream.
 
would you like to write some example code(methode) for sender and listener:
1. using UDP
2. send a TMEmorystream
3. the listener (aSocket or whatever) can receive data as a Tmemorystream or processed to be TMemory stream.

4.  whatever the component(indy, ics, synapse, etc...) used as long it's work on delphi 2007, it's ok

thanks
0
Comment
Question by:pete_03
  • 3
  • 3
  • 2
8 Comments
 
LVL 17

Expert Comment

by:TheRealLoki
Comment Utility
with Indy you'd use SendBuffer(Buffer, count) and Read(Buffer, count_)

here's a very simple example I wrote using a TStringStream...
using a TMemoryStream is similar, but a stringstream is easier to demonstrate

procedure TForm1.eSendKeyPress(Sender: TObject; var Key: Char);

var

  s: string;

  Buffer: Array [0..maxBufferSize] of Byte;

  count: Integer;

  stream: TStringStream;

begin

  if ord(Key) = vk_Return then

  begin

    Key := #0;

// now send this
 

    s := eSend.Text;
 

    IdUDPClient1.Host := 'localhost';

    IdUDPClient1.Port := StrToIntDef(eClientPort.Text, 1234);
 

    stream := TStringStream.Create(S);
 

    stream.Seek(0, soFromBeginning);

    stream.Read(Buffer, Stream.Size);

    IdUDPClient1.SendBuffer(Buffer, stream.size);
 

// you can also use the methof below

// or of course you can just use IdUDPClient1.Send(AData: string)

{

    s := eSend.Text;

    count := length(s);

    move(s[1], Buffer, count);

    IdUDPClient1.Host := 'localhost';

    IdUDPClient1.Port := StrToIntDef(eClientPort.Text, 1234);

    IdUDPClient1.SendBuffer(Buffer, count);

}

  end;

end;

Open in new window

0
 

Author Comment

by:pete_03
Comment Utility
thanks for reply, i am beginner of delphi, could wrap that code to a methode like:
procedure sendstream(aMemoryStream: TMemorystream) as easy as : nmUDP1.sendstream(myMemorystream)

and how about the listener ?
0
 
LVL 17

Expert Comment

by:TheRealLoki
Comment Utility
show me your exact example of what you ant (i.e. your nmUDP code)
and I will show you how to do the equivalent in Indy.
The bit I need to understand is if you need to send the "size" of the stream first, or if you do not need the size
0
 

Author Comment

by:pete_03
Comment Utility
procedure TMainModule.SendRecordValue(FRemoteHost: String; FPort: Integer);
var FMemoryStream: TMemoryStream;
    i : Byte;
    FValue : Single;
begin
   FMemoryStream := TMemoryStream.Create;
   try;
      for i := 0 to (record.Count-1) do
      begin
        FValue := record.Value[i];
        FMemoryStream.Write(FValue, SizeOf(FValue));
      end;

      NMUDP1.RemoteHost := FRemoteHost;
      NMUDP1.RemotePort := FPort;
      NMUDP1.SendStream(FMemoryStream);

   finally
      FMemoryStream.Free;
   end;
end;






procedure TfrmMonitoring.NMUDP1DataReceived(Sender: TComponent;
  NumberBytes: Integer; FromIP: String; Port: Integer);
var
    FMemoryStream : TMemoryStream;
    FValue : Single;
    I : Integer;
begin
   if NumberBytes > 0 then
   begin
      FByteReceived := FByteReceived + NumberBytes;
      FMemoryStream := TMemoryStream.Create;
      try
         NMUDP1.ReadStream(FMemoryStream);
         FMemoryStream.Position := 0;
         i := 0;
         repeat
            FMemoryStream.Read(FValue, SizeOf(FValue));
            ClientRecord.Value[i] := FValue;
            Inc(i);
         until (FMemoryStream.Position >= FMemoryStream.Size);
      finally
         FMemoryStream.Free;
      end;
   end;

0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 36

Expert Comment

by:Geert Gruwez
Comment Utility
I mostly use a TStringList to send strings ...

you may need to check if ClientRecord.RecordCount works

procedure TForm1.SendRecordValue(aRemoteHost: String; aPort: Integer);

var i : Byte;

    List: TStringList;

begin

  List := TStringList.Create;

  try

    for i := 0 to (record.Count-1) do

      List.Add(Record.Value[i]);

    IdUDPClient1.Send(aRemoteHost, aPort, List.Text);

  finally

    List.Free;

  end;

end;
 

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;

  ABinding: TIdSocketHandle);

var

  I : Integer;

  List: TStringList;

  Stream: TStringStream;

begin

  ClientRecord.RecordCount := 0;

  if AData.Size > 0 then

  begin

    List := TStringList.Create;

    try

      Stream := TStringStream.Create('');

      try

        Stream.CopyFrom(AData, AData.Size);

        List.Text := Stream.DataString;

      finally

        Stream.Free;

      end;

      ClientRecord.RecordCount := List.Count;

      for I := 0 to List.Count - 1 do

        ClientRecord.Value[i] := List[I];

    finally

      List.Free;

    end;

  end;

end;

Open in new window

0
 

Author Comment

by:pete_03
Comment Utility
on idUDP server, i doubleclick at onUDPRead Event then on editor:
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TBytes;
  ABinding: TIdSocketHandle);


procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
  ABinding: TIdSocketHandle);

it's raises error, the parameters AData should be Tbytes instead TStream.
then i forced to change the parameters type to TStream as you suggest, application compiled successfully, i set a breakpoint  at this event, nothing fired when the client has sent a udp packet?


i am using indy10, D2007 default packages
0
 
LVL 36

Expert Comment

by:Geert Gruwez
Comment Utility
oops, that was for Delphi 7

this is for Delphi 2007
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TBytes; ABinding: TIdSocketHandle);

var

  I : Integer;

  List: TStringList;

  Stream: TStringStream;

begin

  //ClientRecord.RecordCount := 0;

  if Length(AData) > 0 then

  begin

    List := TStringList.Create;

    try

      Stream := TStringStream.Create('');

      try

        Stream.Read(AData, Length(AData));

        List.Text :=  Stream.DataString;

        ClientRecord.RecordCount := List.Count;

        for I := 0 to List.Count - 1 do

          ClientRecord.Value[i] := List[I];

      finally

        Stream.Free;

      end;

    finally

      List.Free;

    end;

  end;

end;
 

procedure TForm1.SendRecordValue(aRemoteHost: String; aPort: Integer);

var i : Byte;

    List: TStringList;

begin

  List := TStringList.Create;

  try

    for i := 0 to (record.Count-1) do

      List.Add(Record.Value[i]);

    IdUDPClient1.Host := aRemoteHost;

    IdUDPClient1.Port := aPort;

    IdUDPClient1.Send(List.Text);

  finally

    List.Free;

  end;

end;

Open in new window

0
 
LVL 17

Accepted Solution

by:
TheRealLoki earned 125 total points
Comment Utility
ok, that's all pretty easy
as requested, using your code, I have just added the few things you need

procedure UDPSendStream(UDP_: TIdUDPClient; stream: TStream);

const

  maxBufferSize = 8192; // just make sure this is bigger than you ever need...you can loop but dont know if you need that in your situation

var

  Buffer: Array [0..maxBufferSize] of Byte;

  count: Integer;

begin

  stream.Seek(0, soFromBeginning);

  stream.Read(Buffer, Stream.Size);

  UDP_.SendBuffer(Buffer, stream.size);

end;
 
 

var FMemoryStream: TMemoryStream;

    i : Byte;

    FValue : Single;

begin

   FMemoryStream := TMemoryStream.Create;

   try

      for i := 0 to (record_.Count-1) do

      begin

        FValue := record_.Value[i];

        FMemoryStream.Write(FValue, SizeOf(FValue));

      end;
 

      IdUDPClient1.Host := FRemoteHost;

      IdUDPClient1.Port := FPort;

      UDPSendStream(IdUDPClient1, FMemoryStream);

   finally

      FMemoryStream.Free;

   end;

end;
 
 

procedure TForm1.IdUDPServer2UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);

var

    FMemoryStream : TMemoryStream;

    FValue : Single;

    I : Integer;

begin

   if NumberBytes > 0 then

   begin

      FByteReceived := FByteReceived + NumberBytes;

      FMemoryStream := TMemoryStream.Create;

      try

         FMemoryStream.CopyFrom(AData, AData.Size);

         FMemoryStream.Position := 0;

         i := 0;

         repeat

            FMemoryStream.Read(FValue, SizeOf(FValue));

            ClientRecord.Value[i] := FValue;

            Inc(i);

         until (FMemoryStream.Position >= FMemoryStream.Size);

      finally

         FMemoryStream.Free;

      end;

   end;

end;

Open in new window

0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

In our object-oriented world the class is a minimal unit, a brick for constructing our applications. It is an abstraction and we know well how to use it. In well-designed software we are not usually interested in knowing how objects look in memory. …
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now