Jump to content
bravesofts

Delphi Super Fast LAN tethering in IPv4 network using Indy UDP AutoDiscovery IP

Recommended Posts

A simple, cross-platform demo (VCL + FMX) showing how to Super Fast LAN tethering in IPv4 network Automatically discover a server on the same LAN using UDP Broadcast with Indy components.

582129592_DelphiUDPBroadcastAutoDiscoverypng.thumb.png.494603fb87079c01f4a3fb6961ff9769.png

📌 Overview

This project demonstrates a lightweight, zero-configuration **auto-discovery mechanism**:

  1. - The **Server** listens on a known UDP port (`3434`) for broadcast packets.
  2. - A **Client** (VCL or FMX/Android) sends a broadcast message (`Discovery|Hello...`) on port `3434`.
  3. - The **Server replies** directly to the client (on port `22049`) with its LAN IP address.
  4. - The **Client receives the reply**, extracts the server’s IP, and can then connect via TCP or continue communication.

This makes it possible to build applications that can **find each other on the same LAN instantly** without manual IP setup.

 

🏗 Components Used

  1. - Indy UDP Components

        -  TIdUDPServer.
        -  TIdUDPClient.

    2. - Cross-platform IP detection

        - Windows: `GetAdaptersAddresses` API
        - Android: `Java.Net.NetworkInterface` enumeration
    3. - Thread-safe logging via `TThread.Queue`.
    4. - Timer to control discovery message sending Loop

 

All details has been added in my Github Repo here.

 

Mit Licence: Please feel free to fork and improve & use it on your projects...  

 

Any remarks or suggestions are very wellcome here.

--

thank you All.

Edited by bravesofts
add the goal title
  • Like 4
  • Thanks 2

Share this post


Link to post

I have some issues with your implementation:

  • IPv6 networks are not supported.
  • The client request is needlessly wordy.
  • The client broadcasts to 255.255.255.255 instead of to the subnet's actual broadcast IP. Some routers block traffic to 255.255.255.255 by default.
  • In case the client is run on a machine with multiple networks installed (VPN, etc), there is no option to let the user decide which network to broadcast to.
  • The client is using separate UDP sockets to send the request and read replies. You are forcing the client to receive on a specific listening port. The server is not sending its reply back to the real port that actually sent the request. Most routers will block this traffic if port forwarding is used.  On the server side, always reply to the sending port. On the client side, either 1) let TIdUDPClient read replies on its sending port, or 2) let TIdUDPServer send the request on its listening binding. Use one or the other, not both.
  • Doesn't use Indy's TIdStack.GetLocalAddressList() method to discover local networks (at least on Windows, as it may have issues on Android).

 

Since your goal is to allow a TCP client to discover a server, I would opt to get rid of the TIdUDPServer on the client side, and just use TIdUDPClient by itself.  Send a request, read a response, done.  You don't need to make that process asynchronous with TIdUDPServer in most use cases.  Using TIdUDPServer on the client side makes more sense if you want to discover multiple servers and then let the user choose between them, or to leave it open so servers can just broadcast their presence over time.

Edited by Remy Lebeau
  • Like 6

Share this post


Link to post
7 hours ago, Remy Lebeau said:

Since your goal is to allow a TCP client to discover a server

i really appreciate your reply with remarks & ideas & improvements (IPv6, subnet broadcast, reply-to-sender-port support, multiple NIC handling). etc ...

----------

my goal is Super Fast LAN tethering in IPv4 network Automatic Discovery

but i have a View & a Design Philosophy here:

My view:

  1. Optimize for speed, simplicity, and control in one specific business scenario.
  2. Extra UDP server on client side = intentional handshake/security measure.
  3. “It works everywhere I tested, so good enough.”

Your view:

  1. Optimize for protocol correctness, portability, and edge cases.
  2. Avoid assumptions about broadcast, NAT, routers, IPv4-only, etc.
  3. Make the protocol generic and reusable in any network environment.

My Design Philosophy:
 - Server Side:  
    - Creates a UDP listener on a fixed port (3434 by default).  
    - Waits for broadcast requests with a specific keyword ("Discovery|Hello...").  
    - Responds to the client only if that client has a UDP server listening on another pre-defined port (our “secret port”).  
    - The reply goes to that listening port, not back to the sender’s ephemeral port.  
  
 - Client Side (VCL / FMX):  
    - Uses a UDP server to listen for ServerApp replies on our pre-defined “secret port”.  
    - Uses a UDP client socket to broadcast a discovery request Help.  
    - The server is forced to reply on our pre-defined “secret port”, and will only reply if the client has a listening UDP server on the agreed-upon port → this is our security + filtering mechanism here.  
    - After receiving the reply, the client knows the TCP server IP/port and can connect quickly.  

 

Why it feels “super fast”:  
  - You don’t waste time scanning subnets.  
  - You don’t query all adapters manually. You just blast 255.255.255.255:3434 and whoever is alive responds.  
  - The “secret UDP server port” acts as handshake validation, so random broadcasts don’t get replies.  
  - No retries, no handshakes, no multi-round protocols, no user help at alljust one broadcast, one reply
  

Conclusion:

  1. My approach is fast, pragmatic, secure, and business-oriented.
  2. Remy’s advice is about protocol correctness, portability, and avoiding future bugs.
Edited by bravesofts
  • Confused 1

Share this post


Link to post

Forcing use of client/server components on specific ports does not provide security. Nor are your "secret" ports actually very secret, they are easily discoverable. Also, the server has no way to know if the client is even listening on the "secret" port before replying, so there's no security in favoring one port over another. If you want true security, use a proper security protocol, like DTLS.


Also, using an asynchronous server component to receive 1 response is not making the client faster and simpler, it's actually making the client slower and complex (multi-thread handling, breaking up code flow, etc), and it goes against one of Indy's core designs - linear writes and reads in command/response models.
 

But whatever. It's your business design, do what makes sense to you. What do I know? I'm just the guy who maintains the components you are basing your work on.  Good luck.

  • Haha 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×