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

x
?
Solved

send receive TMemorystream over UDP

Posted on 2008-10-21
8
Medium Priority
?
2,098 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
ID: 22771800
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
ID: 22772131
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
ID: 22772713
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:pete_03
ID: 22772762
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
 
LVL 38

Expert Comment

by:Geert Gruwez
ID: 22773907
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
ID: 22775029
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 38

Expert Comment

by:Geert Gruwez
ID: 22775544
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 500 total points
ID: 22801368
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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
Suggested Courses

564 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