Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: IDUPSERVER send message to a spicific client



Permlink Replies: 19 - Last Post: Dec 18, 2017 8:46 AM Last Post By: madammar ellias
madammar ellias

Posts: 111
Registered: 8/17/17
IDUPSERVER send message to a spicific client
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 7, 2017 9:40 AM
i am trying to understand the usage of idudpserver this is the basicserver code


unit UDPSRV;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdBaseComponent, IdComponent, IdUDPBase,
  IdUDPServer, IdGlobal, IdSocketHandle, Vcl.StdCtrls;
 
type
  Tudpservfrm = class(TForm)
    udpserver: TIdUDPServer;
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    procedure udpserverUDPRead(AThread: TIdUDPListenerThread;
      const AData: TIdBytes; ABinding: TIdSocketHandle);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure UpdateBindings;
  public
    { Public declarations }
  end;
 
var
  udpservfrm: Tudpservfrm;
 
implementation
 
{$R *.dfm}
 
procedure Tudpservfrm.Button1Click(Sender: TObject);
begin
 UpdateBindings;
 
 udpserver.Active := true;
end;
 
procedure Tudpservfrm.udpserverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
//
//memo1.Lines.Add(bytestostring(AData));
 
 
end;
 
procedure Tudpservfrm.UpdateBindings;
var
Binding: TIdSocketHandle;
begin
udpserver.DefaultPort := StrToInt(Edit1.Text);
udpserver.Bindings.Clear;
Binding := udpserver.Bindings.Add;
Binding.IP := '0.0.0.0';
Binding.Port := StrToInt(Edit1.Text);
end;
 
end.

and here is the client application

unit udpfrm;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdBaseComponent, IdComponent, IdUDPBase,
  IdUDPClient, Vcl.StdCtrls, Vcl.ExtCtrls, IdUDPServer, IdGlobal, IdSocketHandle;
 
type
  TUDPClient = class(TForm)
    Button1: TButton;
    tmr1: TTimer;
    Memo1: TMemo;
    udpreciver: TIdUDPServer;
    procedure Button1Click(Sender: TObject);
    procedure tmr1Timer(Sender: TObject);
    procedure udpreciverUDPRead(AThread: TIdUDPListenerThread;
      const AData: TIdBytes; ABinding: TIdSocketHandle);
    procedure udpreciverStatus(ASender: TObject; const AStatus: TIdStatus;
      const AStatusText: string);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  UDPClient: TUDPClient;
 
implementation
 
{$R *.dfm}
 
procedure TUDPClient.Button1Click(Sender: TObject);
begin
  if not udpreciver.Active then
  begin
    udpreciver.Active := True;
    udpreciver.Send('127.0.0.1',6754,'ping');
    tmr1.Enabled := True;
  end;
 
{udpclient.Host := '127.0.0.1';
udpclient.Port := 6754;
udpclient.Connect;}
end;
 
procedure TUDPClient.tmr1Timer(Sender: TObject);
begin
  try if udpreciver.Active then
 
   udpreciver.Send('127.0.0.1',6754,'ping');
 
   except end;
end;
 
procedure TUDPClient.udpreciverStatus(ASender: TObject;
  const AStatus: TIdStatus; const AStatusText: string);
begin
 
memo1.Lines.Add(AStatusText);
 
end;
 
procedure TUDPClient.udpreciverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
memo1.Lines.Add(bytestostring(AData));
end;
 
end.
 


i am using another idudpserver to communicate with the main server is that okay?

also how can i make the server to send data to a specific clients ?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: IDUPSERVER send message to a spicific client
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 7, 2017 11:10 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

i am using another idudpserver to communicate with the main server is
that okay?

Yes, that is fine. UDP is connectionless, so it is possible to have 2
TIdUDPClient communicate with each other, and 2 TIdUDPServer
communicate with each other. There is no strict client/server modal,
like with TCP.

also how can i make the server to send data to a specific clients ?

Simply specify the desired client IP/port when calling the Send...()
methods of the appropriate Binding object.

Typically, you would send a reply back to a client in the server's
OnUDPRead event, using the provided ABinding parameter and its
PeerIP/PeerPort properties.

If you want to send data from outside that event, you will have to keep
track of the PeerIP/PeerPort and go directly to the server's Bindings
collection to access the desired Binding. If you create multiple
binding objects, you will have to also keep track of which one is able
to reach the client so you can use that Binding to send data.

--
Remy Lebeau (TeamB)
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 7, 2017 4:03 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Simply specify the desired client IP/port when calling the Send...()
methods of the appropriate Binding object.

Typically, you would send a reply back to a client in the server's
OnUDPRead event, using the provided ABinding parameter and its
PeerIP/PeerPort properties.

If you want to send data from outside that event, you will have to keep
track of the PeerIP/PeerPort and go directly to the server's Bindings
collection to access the desired Binding. If you create multiple
binding objects, you will have to also keep track of which one is able
to reach the client so you can use that Binding to send data.

--
Remy Lebeau (TeamB)

i have tried to sendback data from server to all other client app but i did not receive

thats what i did



procedure Tudpservfrm.udpserverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
//
memo1.Lines.Add(bytestostring(AData) + Abinding.IP);
 
//ABinding.Send('pong'); this does not send any thing to all clients app
 
//after that i have did something like this 
 
Athread.Server.Send(ABinding.PeerIP, ABinding.PeerPort, 'Pong');// but this does not send to all connected clients
 
end; 
 


here is the client app code
procedure TUDPClient.udpreciverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
memo1.Lines.Add(bytestostring(AData) + Abinding.IP);
end;
 
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 7, 2017 5:25 PM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

i have tried to sendback data from server to all other client app but
i did not receive

You can't use TIdSocketHandle.Send() unless you statically connect the
binding to a specific peer, which you are not doing.

Calling Server.Send() will call TIdSocketHandle.SendTo() on the 1st
item in the Bindings collection. You should be using ABinding.SendTo()
instead (and make sure TIdUDPServer.ThreadedEvent is set to False since
you are accessing the UI directly):

procedure Tudpservfrm.udpserverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
  //
  memo1.Lines.Add(bytestostring(AData) + Abinding.IP);
 
  ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, 'Pong');
end; 


--
Remy Lebeau (TeamB)
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 7, 2017 5:38 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

You can't use TIdSocketHandle.Send() unless you statically connect the
binding to a specific peer, which you are not doing.

Calling Server.Send() will call TIdSocketHandle.SendTo() on the 1st
item in the Bindings collection. You should be using ABinding.SendTo()
instead (and make sure TIdUDPServer.ThreadedEvent is set to False since
you are accessing the UI directly):

procedure Tudpservfrm.udpserverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
  //
  memo1.Lines.Add(bytestostring(AData) + Abinding.IP);
 
  ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, 'Pong');
end; 


--
Remy Lebeau (TeamB)

i am able to receive with ABinding but ABinding cannot be expand it does not have sendbuffer both of them send data to client itself but all other active clients does not receive , as example i do something like this

Athread.Server.Send(ABinding.PeerIP, ABinding.PeerPort, bytestostring(AData));

i dont want to send the Adata to the client itself i wanted to send to all other peers Active weather i wanted to send normal text or send a buffer

and thats brings me to the specific mechanism understanding , which in tcp were very easy by defining connection class and choose to write to others or self , in UDP is diffrent case i am totally new to it
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 8, 2017 7:26 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

Calling Server.Send() will call TIdSocketHandle.SendTo() on the 1st
item in the Bindings collection. You should be using ABinding.SendTo()
instead (and make sure TIdUDPServer.ThreadedEvent is set to False since
you are accessing the UI directly):

--
Remy Lebeau (TeamB)

i am currently use abinding sendto
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, AData); 
 


sender client is received but other connected clients does not read should i loop through something i am trying to understand how to work with it
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 8, 2017 8:24 PM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

i am currently use abinding sendto
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, AData); 
 


sender client is received but other connected clients does not read

Of course not, because you are sending back to one specific client -
the one you received from.

should i loop through something

If you want to send back to multiple clients, then you have to keep
track of their PeerIP/PeerPort in a list and then call SendTo() for
each one. Or, call SendTo() one time to send to a broadcast/multicast
IP/Port that all clients are listening/subscribed to.

--
Remy Lebeau (TeamB)
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 9, 2017 2:37 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

If you want to send back to multiple clients, then you have to keep
track of their PeerIP/PeerPort in a list and then call SendTo() for
each one. Or, call SendTo() one time to send to a broadcast/multicast
IP/Port that all clients are listening/subscribed to.

--
Remy Lebeau (TeamB)

that's means that udp is very limited to send data to only ip/port , not like the tcp client class which gives ability to send data to a connection based on any values matched .

i was building this server to avoid streaming using tcp which udp in this case cannot help because i have too many channels on the same server ip/port which will make udp send data to all of them without ability to choose which destination could receive on the same ip/port .
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 9, 2017 8:32 AM   in response to: madammar ellias in response to: madammar ellias
Am 09.12.2017 um 11:37 schrieb madammar ellias:
Remy Lebeau (TeamB) wrote:

If you want to send back to multiple clients, then you have to keep
track of their PeerIP/PeerPort in a list and then call SendTo() for
each one. Or, call SendTo() one time to send to a broadcast/multicast
IP/Port that all clients are listening/subscribed to.

--
Remy Lebeau (TeamB)

that's means that udp is very limited to send data to only ip/port , not like the tcp client class which gives ability to send data to a connection based on any values matched .

i was building this server to avoid streaming using tcp which udp in this case cannot help because i have too many channels on the same server ip/port which will make udp send data to all of them without ability to choose which destination could receive on the same ip/port .

Hello,

as already written elsewhere here by me: TCP is connection oriented, so
you have a connection to hold on. UDP is not. UDP is: send it and forget
it sort of. If it reaches destination then OK, if not, you won't notice
on the sender side.

On the other hand its more light weight and if you need to send the very
same thing to many clients you can send it as multicast or broadcast.
Somewthing TCP cannot.

Greetings

Markus
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 10, 2017 6:16 PM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:
Hello,

as already written elsewhere here by me: TCP is connection oriented, so
you have a connection to hold on. UDP is not. UDP is: send it and forget
it sort of. If it reaches destination then OK, if not, you won't notice
on the sender side.

On the other hand its more light weight and if you need to send the very
same thing to many clients you can send it as multicast or broadcast.
Somewthing TCP cannot.

Greetings

Markus

yes i have already get this point i am not trying to make TCP UDP mashup , i am trying to understand the possibility of sending data to an ip address and port where this ip address is equal something which obvious this cannot be done in udp . problem here what if i have 3 computers on the same ip address ?
i know every new subscriber have different port to communicate with but this is not enough this maybe work for a single data transfer purpose . but multichannel communicating need to be specific .
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: IDUPSERVER send message to a spicific client [Edit] [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 11, 2017 12:23 AM   in response to: madammar ellias in response to: madammar ellias
Am 11.12.2017 um 03:17 schrieb madammar ellias:
Markus Humm wrote:
Hello,

as already written elsewhere here by me: TCP is connection oriented, so
you have a connection to hold on. UDP is not. UDP is: send it and forget
it sort of. If it reaches destination then OK, if not, you won't notice
on the sender side.

On the other hand its more light weight and if you need to send the very
same thing to many clients you can send it as multicast or broadcast.
Somewthing TCP cannot.

Greetings

Markus

yes i have already get this point i am not trying to make TCP UDP mashup , i am trying to understand the possibility of sending data to an ip address and port where this ip address is equal something which obvious this cannot be done in udp . problem here what if i have 3 computers on the same ip address ?
i know every new subscriber have different port to communicate with but this is not enough this maybe work for a single data transfer purpose . but multichannel communicating need to be specific .

Huh?
You do not want to have 3 PCs with the same IP address in any network.
That only creates trouble.

I'm still not sure what you really want to do.

I guess you have a server and you want to send some video/audio streams
to different PCs. Right? Is it the same stream to every PC or different
streams depending on what the client was requesting?

Greetings

Markus
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client [Edit] [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 11, 2017 5:21 AM   in response to: Markus Humm in response to: Markus Humm
Markus Humm wrote:

Huh?
You do not want to have 3 PCs with the same IP address in any network.
That only creates trouble.

I'm still not sure what you really want to do.

I guess you have a server and you want to send some video/audio streams
to different PCs. Right? Is it the same stream to every PC or different
streams depending on what the client was requesting?

Greetings

Markus

yes that's what i am trying to do i have one server and the client side have channels that connected to that server , client can stream on each channel and every client the joined the channel start listening to streaming that certain to this channel
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: IDUPSERVER send message to a spicific client [Edit] [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 11, 2017 5:43 AM   in response to: madammar ellias in response to: madammar ellias
Am 11.12.2017 um 14:21 schrieb madammar ellias:
Markus Humm wrote:

Huh?
You do not want to have 3 PCs with the same IP address in any network.
That only creates trouble.

I'm still not sure what you really want to do.

I guess you have a server and you want to send some video/audio streams
to different PCs. Right? Is it the same stream to every PC or different
streams depending on what the client was requesting?

Greetings

Markus

yes that's what i am trying to do i have one server and the client side have channels that connected to that server , client can stream on each channel and every client the joined the channel start listening to streaming that certain to this channel

Server could get all the streams via UDP to different port numbers.
Every channel has its ofn port number and all the data streamed for that
channel will be broadcasted via UDP by the server to that port number.

A client wishing to receive a certain channel just has to create an UDP
listener on that port number.

Greetings

Markus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: IDUPSERVER send message to a spicific client [Edit] [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 11, 2017 11:37 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

yes that's what i am trying to do i have one server and the client
side have channels that connected to that server , client can stream
on each channel and every client the joined the channel start
listening to streaming that certain to this channel

You should create a separate multicast group for each channel. Then
clients can subscribe to individual groups as needed. When you send
data to a group's single IP/Port, all clients subscribed to the group
will receive the same data. Don't try to handle the broadcasting
manually, let the network do the hard work for you.

Indy has multicast components - TIdIPMCastClient and TIdIPMcastServer.

--
Remy Lebeau (TeamB)
Markus Humm

Posts: 5,113
Registered: 11/9/03
Re: IDUPSERVER send message to a spicific client [Edit] [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 12, 2017 10:07 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Am 11.12.2017 um 20:37 schrieb Remy Lebeau (TeamB):
madammar ellias wrote:

yes that's what i am trying to do i have one server and the client
side have channels that connected to that server , client can stream
on each channel and every client the joined the channel start
listening to streaming that certain to this channel

You should create a separate multicast group for each channel. Then
clients can subscribe to individual groups as needed. When you send
data to a group's single IP/Port, all clients subscribed to the group
will receive the same data. Don't try to handle the broadcasting
manually, let the network do the hard work for you.

Indy has multicast components - TIdIPMCastClient and TIdIPMcastServer.

Ok, that's new for me as well and good info!
Didn't do too much with UDP yet.

Greetings

Markus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 11, 2017 11:33 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

that's means that udp is very limited to send data to only ip/port ,
not like the tcp client class which gives ability to send data to a
connection based on any values matched .

Matched to what? I don't understand what you are saying.

To send data to a specific TCP client, all you need is the SOCKET that
is associated with that client. To send data to a specific UDP client,
all you need is the PeerIP/PeerPort of that client, you can use any
SOCKET that is attached to the same network as that client.

So what is the difference? It is your responsibility to keep track of
clients one way or another so you can pick which one you want to send
to when needed.

i was building this server to avoid streaming using tcp which udp in
this case cannot help because i have too many channels on the same
server ip/port which will make udp send data to all of them without
ability to choose which destination could receive on the same ip/port.

I don't understand what you are describing. But if you want to stream
the same data to multiple UDP clients simultaneously, you really should
by using UDP broadcasting or IP multicasting for that purpose, that is
what they are specifically designed for.

I think you are completely misunderstanding how TCP and UDP actually
work, and how to use them effectively.

--
Remy Lebeau (TeamB)
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 11, 2017 5:19 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

I don't understand what you are describing. But if you want to stream
the same data to multiple UDP clients simultaneously, you really should
by using UDP broadcasting or IP multicasting for that purpose, that is
what they are specifically designed for.

I think you are completely misunderstanding how TCP and UDP actually
work, and how to use them effectively.

--
Remy Lebeau (TeamB)

when i talked about TCP connection value i was talking about the client class that can define some variables to each client sorry for misunderstand , i am confused because this is my first time to use udp , i will start looking at indy ip multicast component
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: IDUPSERVER send message to a spicific client [Edit]
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 12, 2017 11:24 AM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:
when i talked about TCP connection value i was talking about the client class
that can define some variables to each client

That is because in TCP, there is an actual connection and a 1:1 relationship between client and server, and so the TIdTCPServer keeps track of those connections for you for convenience.

i am confused because this is my first time to use udp

In UDP, there is no connection between client and server, and no 1:1 relationship either. If you need to track clients, you have to do that manually, which you can do because UDP clients usually have to announce themselves to the server in order to get responses back.

i will start looking at indy ip multicast component

In multicast, there is also no connection and no 1:1 relationship. But also, clients don't announce themselves to the server, so it is unaware that they even exist. A multicast server is simply pushing data out to the network, and the network delivers the data to whoever asks the network for it. There is no direct communication between clients and the server. If you need that communication, you have to do it separately using UDP or TCP.

--
Remy Lebeau (TeamB)
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 15, 2017 10:47 PM   in response to: madammar ellias in response to: madammar ellias
back to udp server to server

now i have created something like this to communicate between clients is it a good way ? i trying to learn

type
  Tudpservfrm = class(TForm)
    udpserver: TIdUDPServer;
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    VDT1: TVirtualStringTree;
    procedure udpserverUDPRead(AThread: TIdUDPListenerThread;
      const AData: TIdBytes; ABinding: TIdSocketHandle);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure VDT1FreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
    procedure VDT1GetNodeDataSize(Sender: TBaseVirtualTree;
      var NodeDataSize: Integer);
    procedure VDT1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
  private
    { Private declarations }
    procedure UpdateBindings;
    procedure Add_Item(ipada: string; porta: integer);
    function lookingTreeView(vsttosrch: TVirtualStringTree; ipad: String;
      prtnuma: integer): PVirtualNode;
  public
    { Public declarations }
  end;
 
 
  type
  Tuserdataclass = class
  private
  Fipaddr : string;
  Fportnum : integer;
  public
  property ipaddr: String read Fipaddr write Fipaddr;
  property portnum: integer read Fportnum write Fportnum;
  constructor Create;
  destructor Destroy; override;
  end;
 
type
PUserData = ^TUserData;
 
TUserData = record
FObject: Tuserdataclass;
end;
 
 
var
  udpservfrm: Tudpservfrm;
 
implementation
 
{$R *.dfm}
 
function AddVSTStructure(AVST: TCustomVirtualStringTree; ANode: PVirtualNode; AObject: Tuserdataclass): PVirtualNode;
var
Data: PUserData;
begin
Result := AVST.AddChild(ANode);
Data := AVST.GetNodeData(Result);
AVST.ValidateNode(Result, false);
Data^.FObject := AObject;
end;
 
 
procedure Tudpservfrm.Add_Item(ipada : string; porta : integer);
var
userdataclass : Tuserdataclass;
begin
 
VDT1.BeginUpdate;
try
begin
 
userdataclass := Tuserdataclass.Create;
userdataclass.ipaddr := ipada;
userdataclass.portnum := porta;
 
 
AddVSTStructure(VDT1, nil, userdataclass);
 
end;
 
 
finally
VDT1.EndUpdate;
end;
 
end;
 
procedure Tudpservfrm.Button1Click(Sender: TObject);
begin
 UpdateBindings;
 
 udpserver.Active := true;
end;
 
procedure Tudpservfrm.FormCreate(Sender: TObject);
begin
VDT1.NodeDataSize := SizeOf(TUserData);
end;
 
procedure Tudpservfrm.udpserverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
var
I : integer;
datastring, command : string;
Node: PVirtualNode;
Data: PUserData;
Nodesend: PVirtualNode;
Datasend: PUserData;
begin
datastring := bytestostring(AData);
command := copy(datastring,1,pos('~',datastring)-1);//parse
 
 
if command = 'login' then
begin
Add_item(ABinding.PeerIP, ABinding.PeerPort);
end else
 
if command = 'logout' then
begin
 
Node := lookingTreeView(vdt1, ABinding.PeerIP, ABinding.PeerPort);
Data := VDT1.GetNodeData(Node);
 
if Node <> nil then
begin
VDT1.DeleteNode(Node);
end;
 
end;
 
Nodesend := Vdt1.GetFirst();
 
while Nodesend <> nil do
begin
Datasend := vdt1.GetNodeData(Nodesend);
Abinding.SendTo(Datasend.FObject.ipaddr, Datasend.FObject.portnum, Adata);
Nodesend := vdt1.GetNext(Nodesend);
end;
 
 
end;
 
function Tudpservfrm.lookingTreeView(vsttosrch: TVirtualStringTree; ipad: String; prtnuma:integer): PVirtualNode;
var
Node: PVirtualNode;
Data: PUserData;
begin
Result := nil;
Node := vsttosrch.GetFirst;
while Node <> nil do
begin
Data := vsttosrch.GetNodeData(Node);
if (Data.FObject.ipaddr = ipad) And (Data.FObject.portnum = prtnuma) then
begin
Result := Node;
break;
end
else
Node := vsttosrch.GetNext(Node);
end;
end;
 
 
procedure Tudpservfrm.UpdateBindings;
var
Binding: TIdSocketHandle;
begin
udpserver.DefaultPort := StrToInt(Edit1.Text);
udpserver.Bindings.Clear;
Binding := udpserver.Bindings.Add;
Binding.IP := '0.0.0.0';
Binding.Port := StrToInt(Edit1.Text);
end;
 
procedure Tudpservfrm.VDT1FreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
Data: PUserData;
begin
Data := VDT1.GetNodeData(Node);
if Assigned(Data) then
Data.FObject.Free;
end;
 
procedure Tudpservfrm.VDT1GetNodeDataSize(Sender: TBaseVirtualTree;
  var NodeDataSize: Integer);
begin
NodeDataSize := SizeOf(TUserData);
end;
 
procedure Tudpservfrm.VDT1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
Data: PUserData;
begin
  Data:= VDT1.GetNodeData(Node);
  case Column of
 0: CellText := Data.FObject.ipaddr + ' Port : ' + intTostr(Data.FObject.portnum);
  end;
 
end;
 
{ Tuserdataclass }
 
constructor Tuserdataclass.Create;
begin
 
end;
 
destructor Tuserdataclass.Destroy;
begin
 
  inherited;
end;
 
end.


Edited by: madammar ellias on Dec 17, 2017 8:33 PM
madammar ellias

Posts: 111
Registered: 8/17/17
Re: IDUPSERVER send message to a spicific client
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 18, 2017 8:46 AM   in response to: madammar ellias in response to: madammar ellias
i have turned the multi thread to true

here what the code looks like now i have horible feeling that i am doing it very bad i already can communicate with each one that subscribed to that port , but i want to do it right is the code looks fine ?

procedure Tudpservfrm.udpserverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
var
I : integer;
datastring, command : string;
Node: PVirtualNode;
Data: PUserData;
Nodesend: PVirtualNode;
Datasend: PUserData;
begin
datastring := bytestostring(AData);
command := copy(datastring,1,pos('~',datastring)-1);//parse
 
 
if command = 'login' then
begin
TThread.Synchronize(nil,
procedure
begin
Add_item(ABinding.PeerIP, ABinding.PeerPort, ABinding.Port);
end);
 
end else
 
if command = 'logout' then
begin
TThread.Synchronize(nil,
procedure
begin
Node := lookingTreeView(vdt1, ABinding.PeerIP, ABinding.PeerPort, ABinding.Port);
Data := VDT1.GetNodeData(Node);
 
if Node <> nil then
begin
VDT1.DeleteNode(Node);
end;
end);
end else
begin
TThread.Synchronize(nil,
procedure
begin
 
Nodesend := Vdt1.GetFirst();
 
while Nodesend <> nil do
begin
Datasend := vdt1.GetNodeData(Nodesend);
 
if (Datasend.FObject.aserverport = ABinding.Port)
And (Datasend.FObject.portnum <> ABinding.PeerPort) then
begin
Abinding.SendTo(Datasend.FObject.ipaddr, Datasend.FObject.portnum, Adata);
end;
 
Nodesend := vdt1.GetNext(Nodesend);
end;
end);
end;
 
 
end;
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02