Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   Delphi Netzwerk-Broadcast mit Win.-API (https://www.delphipraxis.net/109054-netzwerk-broadcast-mit-win-api.html)

BrightAngel 23. Feb 2008 16:17


Netzwerk-Broadcast mit Win.-API
 
Hey!
Ich weis, ihr denkt jetzt: oh nee net schon wieder die selben Fragen... Wann lernen die endlich die Suchfunktion zu benutzen...
Ich such jetzt schon seit Tagen im Web und im Forum, aber bisher ohne Erfolg.

Ich müsste in vbscript eine Netzwerkverbindung aufbauen, was allerdings nicht geht.
[edit](Weil ich kein COM-Object registrieren darf...)
(Falls ihr wisst, wie man ne dll sonst über vbs läd, könntet ihr mir des dann auch erklären, weil sonst lass ich en programm ausführen...) thx [/edit]
Also dachte ich mir: Dann schreib dir halt eine art "Dienstprogramm", welches das für dich erledigt. Soweit so gut; Jetzt aber das Hindernis: Ich will+darf keine Komponentensammlungen wie Indy oder dergleichen verwenden.

Zu meinem Problem:
Ich möchte alle im Netzwerk laufenden Instanzen meines "Dienstprogramms" auflistet.
Ich dachte an Broadcast mittels UDP-Protokoll, welches bei Indy ja recht einfach geht, indem ich Broadcast auf True setze, usw.

So, jetzt will ich was dabei lernen und will das mit der WinAPI "nachbauen"
(könnte ich das auch mit TSocket machen??? Wenn ja: Wie?)


Falls ich komplett auf dem Holzweg bin: bitte weckt mich.^^

Hoffe auf Eure Hilfe und Erfahrung, schonmal im vorraus danke,
BrightAngel

sx2008 23. Feb 2008 16:31

Re: Netzwerk-Broadcast mit Win.-API
 
TSocket fällt aus, da es nur für TCP (IP V4) gebaut wurde.
Die API, auf die alle Komponenten zurückgreifen ist WinSock2.

Du kannst dir ja mal die TUDPSocket Komponente downloaden und untersuchen,
wie es gemacht wird.
http://www.torry.net/pages.php?id=220

BrightAngel 23. Feb 2008 16:37

Re: Netzwerk-Broadcast mit Win.-API
 
Danke für den Tipp!
Aber das hab ich schon gemacht und habe herausgefunden, dass das auf dass TSockAddr, welches Bestandteil derFunction SendTo ist in der Indy-Sammlung liegt...
Ich will das eig. auch nicht mit einer Kompo. machen, es sei denn es geht nicht anders.
Das mit dem TSocket dacht ich mir zwar schon, aber ich wollt auf nummer sicher gehen...
Danke für die Antwort.

Brighty

sirius 23. Feb 2008 16:45

Re: Netzwerk-Broadcast mit Win.-API
 
Ich hatte mir dazu mal ein Beispielprogramm geschrieben. Ich habs mal kurz für Broadcast umgebaut.
Delphi-Quellcode:
uses
  winsock,
  windows;

Procedure HandleError;
Var   ErrorCode:Integer;
   S:String;
   Len:Integer;
Begin
   ErrorCode := WSAGetLastError;

   setlength(s, 260);
   Len:= Formatmessage(   Format_Message_from_System,
                  nil,errorCode,0,@s[1],length(s),nil);
   setlength(s, Len);

   MessageBox(   0,pchar(s),'Socket Error',
      MB_OK or MB_ICONERROR or MB_TASKMODAL);
        //raiseException wäre hier auch nicht schlecht
End;

Procedure InitSockets;
Var   Data:WSAData;
Begin
   If WSAStartup( MakeWord(1,1), Data) = SOCKET_ERROR then
      HandleERROR;
End;

Function createSocket_UDP:TSocket;
Begin
   Result :=   socket(   AF_INET,
               SOCK_DGRAM,
               IPProto_UDP); //Socket erstellen

   If Result = INVALID_SOCKET then HandleError;
End;

Procedure sendbuf_via_UDP(IP:string; Port:Word; var buf; buflen:Integer);
const BC:bool=true;
Var   SockAddr:TSockAddrIn;
   AddrLen:Integer;
   FSocket:TSocket;

Begin

   FSocket := createSocket_UDP;

        setsockopt(FSocket,SOL_SOCKET,SO_BroadCast,@BC,sizeof(BC)); //BroadCast ein

   AddrLen := sizeof(SockAddr);

   SockAddr.sin_family := AF_INET;
   SockAddr.sin_Port := htons(Port);
   SockAddr.sin_Addr.S_Addr := inet_addr(PChar(IP));

   If SendTo( FSocket, buf, buflen, 0, SockAddr, AddrLen) = SOCKET_ERROR then
      HandleError;

   CloseSocket( FSocket);
End;


var mystring:string;
begin
  Initsockets;
  Mystring := 'Hallo Du da!';
  Sendbuf_via_UDP('255.255.255.255', 6000, MyString[1], length(Mystring));
  WSACleanUP;
end.
Die Funktionen kannst du ja über die Hilfe bzw. eher über das Windows SDK suchen.
Du kannst natürlich auch alles andere Senden (nicht nur Strings).

BrightAngel 23. Feb 2008 21:36

Re: Netzwerk-Broadcast mit Win.-API
 
Danke für die schnelle Hilfe!
Hat mir sehr weitergeholfen!

Gruß,
Brighty

BrightAngel 24. Feb 2008 09:55

Re: Netzwerk-Broadcast mit Win.-API
 
Hi
Ich hab mich jetzt mal mit diesen Funktionen durch die Hilfe gewühlt und ich denke, dass ich das Prinzip verstanden habe.
Ich hab also jetzt versucht, auch einen Empfänger daraus zu schreiben (also quasi so wie beim ServerSocket).
Die funktion "recv" sa aus, als wäre sie für einen generellen Empfang von Datenpaketen da (also ohne Remote-Adresse).
Stimmt das so? :shock:
Ich hab sie jedenfalls einfach nach dem "SendTo" einfach in Code geschrieben, weil ich dachte, dass bei einem Broadcast ja auch selbst was an mich verschicken müsste, da ich ja im IP-Bereich bin (hab ich glaub irgendwo mal gelesen). :gruebel:

Das Problem ist jetzt aber, dass er sich aufhängt, wenn er die Zeile abgearbeitet hat. Ich hab jetzt das Gefühl, dass das irgendwie asyncron abläuft, also irgendwie: so ich sende was und erst wenn es gesendet ist fang ich an zu hören.
Stimmt das so? :shock:

Gibt es da ne WindowMessage von der Socket-dll aus? :cyclops: Ich hab schon danach gesucht, aber ich habe nichts brauchbares gefunden.

Ich wäre froh, wenn ihr mir hier noch etwas auf die Sprünge helfen könntest.
Gruß,
Brighty

Apollonius 24. Feb 2008 11:18

Re: Netzwerk-Broadcast mit Win.-API
 
Hier findest du eine Liste aller WinSock-Funktionen. Um eine Fenster-Nachricht zu erhalten, musst du WSAAsyncSelect aufrufen.

sirius 24. Feb 2008 11:20

Re: Netzwerk-Broadcast mit Win.-API
 
Liste der Anhänge anzeigen (Anzahl: 1)
recv kann man nehmen, aber recvfrom ist für UDP besser geeignet. Dadurch erfährst du auch, von wem das Päckchen gekommen ist.

Und du hast auch richtig bemerkt, das recv (und auch recvfrom) per default blockierend ist. Das heißt, die Funktion kehrt erst zurück, wenn sie auch etwas empfangen hat (also etwas im Puffer des Sockets liegt). du kannst das Socket natürlich auf nichtblockierend schalten, aber der Ansatz mit der Message ist auch super. Du musst den Befehl WSAAsyncSelect aufrufen. Damit kannst du ein Windowhandle festlegen, an das eine Message gesendet wird, wenn Daten empfangen werden (nebenbei wird dein Socket dadurch auch nichtblockierend). Und dann kannst du recvfrom in der Messgebearbeitung aufrufen.

Eine Annahme von dir ist allerdings falsch. Du bekommst nämlich die Message nicht zurück, zumindest nicht an dein Socket. In meinem Beispiel wird an den Port 6000 gesendet. Und dein Socket liegt irgendwo zwischen 1024 und 5000. Das sucht sich Windows aus beim ersten Sendto. Wenn du den Port deines eigenen Sockets selber festlegen willst, dann benötigst du die Funktion "bind". Dann kannst du den Port zum Senden nehmen und wirst auch gleich die Antwort mitbekommen.

Ich hatte für den Tutorialwettbewerb auf Delphi-Treff ein kleines Programm geschrieben, wo über Buttons jeder einzelne Socket-Befehl ausgeführt wird. (Liegt im Anhang)

BrightAngel 24. Feb 2008 11:36

Re: Netzwerk-Broadcast mit Win.-API
 
Tausend Dank!
Das ist das was ich gesucht hab. Ich denk ich kann so einiges daraus lernen!

Brighty


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:24 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz