Wie kann man andere, laufende Instanzen der eigenen Anwendung im LAN finden?
Ein möglicher Ansatz ist eine Suche per UDP-Broadcast. Da nur im LAN gesucht werden soll (nicht im Internet oder WAN) sollte es keine Probleme mit einem UDP-Broadcast geben (diese werden häufig von Routern ausgefiltert). Für dieses Beispiel wird meine
OpenSource-Komponente TUdpSockUtil verwendet.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| uses ..., UdpSockUtil, WinSock; const SERVICE_PORT = 12345; MY_APP_REQUEST = AnsiString('FindLanInstanceDemo:Request'); MY_APP_REPLY = AnsiString('FindLanInstanceDemo:Reply');
procedure TfrmMain.FormCreate(Sender: TObject); begin UdpSockUtil1.LocalPort := SERVICE_PORT; UdpSockUtil1.RemotePort := SERVICE_PORT; UdpSockUtil1.Broadcast := TRUE; UdpSockUtil1.Open; end;
procedure TfrmMain.btnSearchClick(Sender: TObject); begin UdpSockUtil1.BroadcastText(MY_APP_REQUEST); end; |
Bis hier sind nur Voraussetzungen geschaffen worden. Kommen wir nun zum spannenden Teil, wo ein Datenpaket verarbeitet wird:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure TfrmMain.UdpSockUtil1Receive(Sender: TObject); var SenderIP: in_addr; SenderPort: Integer; SenderData: AnsiString; begin SenderData := UdpSockUtil1.ReceiveText(SenderIP, SenderPort); if (SenderData = MY_APP_REQUEST) then begin UdpSockUtil1.RemoteAddr := SenderIP; UdpSockUtil1.SendText(MY_APP_REPLY); end else if (SenderData = MY_APP_REPLY) then begin SenderData := inet_ntoa(SenderIP); if ListBox1.Items.IndexOf(SenderData) = -1 then ListBox1.Items.Add(SenderData); end else ShowMessage('Unbekanntes Datenpaket von '+inet_ntoa(SenderIP)+':'+IntToStr(SenderPort)); end; |
Hier sind drei Fälle zu unterscheiden:
- Es wurde ein Anfrage-Paket empfangen (MY_APP_REQUEST)
Eine andere Programminstanz (oder ggfs. auch die eigene, Broadcasts werden auch an sich selbst gesendet) fragt nach anderen im LAN. Antwortpaket (nur) an den Absender schicken, damit dieser diese Instanz erkennt.
- Es wurde ein Antwort-Paket empfangen (MY_APP_REPLY)
Vorausgesetzt, wir hatten aus dieser Instanz angefragt, hat eine andere Instanz geantwortet. Absender registrieren andere Instanz gefunden (ggfs. müsste man hier noch die eigene Instanz filtern, Ansatz: jede Instanz bei Programmstart eine GUID bilden lassen und diese mitsenden).
- Es wurde ein Datenpaket mit einem unbekannten Inhalt empfangen
Fehler melden und ignorieren.
In Anhang befindet sich das komplette Demo-Projekt.
Hinweis: Da eine statische Service-Port-Zuordnung gemacht wird, kann man das Programm jeweils nur einmal pro Maschine starten. Für einen Test im LAN sind also mehrere PCs (oder VMs) nötig!
There are 10 types of people - those who understand binary and those who don´t.