Discussion:
TIdUDPClient or TUdpSocket
(too old to reply)
Jean Pion
2006-11-15 09:14:46 UTC
Permalink
Dear readers,

I would like a udp client to listen all the time my application is active.
What I understand is that the Indy client is blocking.
Is there a methode to trick the indy client into being non blocking?
E.g. generating an event if a packet arived.

Or should I use the TUdpSocket, and is so,
can someone please point me to a sample code?

Please advice,

Thanks in advance, Jean.
Remy Lebeau (TeamB)
2006-11-15 10:42:47 UTC
Permalink
Post by Jean Pion
I would like a udp client to listen all the time my application is
active. What I understand is that the Indy client is blocking.
All Indy components are blocking. However, Indy servers are also
multi-threaded. You could use a TIdUDPServer to do what you are asking for.
Post by Jean Pion
Is there a methode to trick the indy client into being non blocking?
No. Indy is not designed for that. Even if you access the socket handle
directly and change it to non-blocking via setsockopt(), you would severely
break Indy by doing that.
Post by Jean Pion
E.g. generating an event if a packet arived.
That is exactly what TIdUDPServer already does for you.


Gambit
Jean Pion
2006-11-15 12:40:31 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Jean Pion
I would like a udp client to listen all the time my application is
active. What I understand is that the Indy client is blocking.
All Indy components are blocking. However, Indy servers are also
multi-threaded. You could use a TIdUDPServer to do what you are asking for.
Post by Jean Pion
Is there a methode to trick the indy client into being non blocking?
No. Indy is not designed for that. Even if you access the socket handle
directly and change it to non-blocking via setsockopt(), you would severely
break Indy by doing that.
Post by Jean Pion
E.g. generating an event if a packet arived.
That is exactly what TIdUDPServer already does for you.
Gambit
If I understand you correct I may setup an aditional UdpServer to receive
the data.
(But this is quite new for me...) My code for sending looks like this:

procedure TMainForm.SendUDPString(IP: String; Port: integer; Data:
String);
begin
IdUDPClient1.Active := True;
IdUDPClient1.Send(IP, Port, Data);
end;

How do I make the answer go to the additional server? Must I set
Binding.PeerPort?
Note: I don't want to use the same port number, because the UdpServer with
that number may be used on the same PC.

Thanks, Jean.
Remy Lebeau (TeamB)
2006-11-15 19:14:27 UTC
Permalink
Post by Jean Pion
If I understand you correct I may setup an aditional UdpServer to
receive the data.
You do not need to use separate client and server components. TIdUDPServer
has the same sending capabilities that TIdUDPClient has. So you can use
TIdUDPServer by itself for all of your sending and receiving needs. You can
have it listening on a port, call Send...() when needed to send outbound
data, and then use the OnUDPRead event to handle inbound data on the
listening port.
You do not need to use the Active property in TIdUDPClient. All it does is
ensures the Binding property is available. Send() calls SendBuffer(), which
does the same thing internally, so the Active property is redundant.
Post by Jean Pion
How do I make the answer go to the additional server?
It is the sender's responsibility to send data to the correct port. If you
use TIdUDPServer for your client's listening, then the port number that the
data is sent from will be the port that the listening socket is bound to.
The other party can send data to that port, and the OnUDPRead event will be
triggered accordingly.
Post by Jean Pion
Must I set Binding.PeerPort?
No.
Post by Jean Pion
I don't want to use the same port number, because the UdpServer
with that number may be used on the same PC.
You have to set a Port for the data to be received on. There is no way to
get around that. That is simply how sockets work in general.


Gambit
Jean Pion
2006-11-16 14:13:48 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Jean Pion
If I understand you correct I may setup an aditional UdpServer to
receive the data.
You do not need to use separate client and server components.
TIdUDPServer
has the same sending capabilities that TIdUDPClient has. So you can use
TIdUDPServer by itself for all of your sending and receiving needs. You can
have it listening on a port, call Send...() when needed to send outbound
data, and then use the OnUDPRead event to handle inbound data on the
listening port.
You do not need to use the Active property in TIdUDPClient. All it does is
ensures the Binding property is available. Send() calls SendBuffer(), which
does the same thing internally, so the Active property is redundant.
Post by Jean Pion
How do I make the answer go to the additional server?
It is the sender's responsibility to send data to the correct port. If you
use TIdUDPServer for your client's listening, then the port number that the
data is sent from will be the port that the listening socket is bound to.
The other party can send data to that port, and the OnUDPRead event will be
triggered accordingly.
Post by Jean Pion
Must I set Binding.PeerPort?
No.
Post by Jean Pion
I don't want to use the same port number, because the UdpServer
with that number may be used on the same PC.
You have to set a Port for the data to be received on. There is no way to
get around that. That is simply how sockets work in general.
Gambit
Thank you for all the help. I finaly solved my problem.

In this case on both sides a Client an a Server are used.
On 1st side Client has port x en Server has port y.
On 2nd side Client has port y en Server has port x.

I expected the Client(s) to receive something after send,
and so I was blocking communication.

It appears that al receipts are handeled by the Server(s).
Which makes sense, because it's non blocking .

Cheers, Jean.

Loading...