Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 11, 2025 22:41

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 26 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: SDL_Net: Broadcast
BeitragVerfasst: So Mai 17, 2009 16:15 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Hi,

wie kann man mit SDL_net einen Broadcast über UDP senden ? Ich habe mir das schon angeschaut, aber es bringt mich nicht weiter. Der erste Störpunkt bei dem Codebeispiel ist, dass es einen Client und Server gibt - der aber nicht existiert, da UDP nunmal verbindungslos ist. Ich will nichts weiter realisieren als eine Spielliste. Alle offenen Spiele sollen angezeigt werden. Daher wäre ein Broadcastpaket sinnvoll, das die anderen erstmal befragt, ob sie das richtige Programm sind und falls sie ein Spiel am Start haben, sollen sie ihre IP zurücksenden, ansonsten nicht. Danach würde ich vorziehen, mit TCP fortzufahren, denn ich halte es für sinnvoll, ein stabiles Protokoll zu verwenden. Soweit ich informiert bin, muss man an 255.255.255.255 senden, um in einem Netzwerk einen Broadcast zu senden. Hier versende ich einfach einen frei gewählten String (log), der als Test dienen soll. Die if-Abfrage in der Schleife trifft allerdings nie zu. Ich muss schon ziemlich blöd sein, denn Google hat mir bisher keine Hilfe dazu geliefert. Das ist für mich ein deutlicher Hinweis, dass hier ein fetter Denkfehler drinnen sein muss.
Code:
  1.   // Nertzwerkkomponente initialisieren
  2.   SDLNet_Init;
  3.   // Socket für Paketsendung öffnen
  4.   Client := SDLNet_UDP_Open(0);
  5.   // Broadcast-IP speichern
  6.   SDLNet_ResolveHost(IP, '255.255.255.255', 2);
  7.   // Platz für das Paket reservieren
  8.   PClient := SDLNet_AllocPacket(512);
  9.   // Paket abfertigen und rausschicken. Hierdurch wird ein Braodcast hervorgerufen, der alle anderen Computer dazu
  10.   // veranlasst, sich zu melden. Daraus entsteht eine Liste mit allen offenen Spielen.
  11.   PClient.Address.Host := IP.Host;
  12.   PClient.Address.Port := IP.Port;
  13.   SDLNet_UDP_Send(Client, -1, PClient);
  14.   // Server zum Paketempfang initialisieren
  15.   Randomize;
  16.   Server := SDLNet_UDP_Open(Random(2000));
  17.   // Platz für das Paket reservieren
  18.   PServer := SDLNet_AllocPacket(512);
  19.  
  20.   while not Fertig do
  21.   begin
  22.     // Eingehende Netzwerkdaten verarbeiten
  23.     if SDLNet_UDP_Recv(Server, PServer) <> -1 then
  24.     begin
  25.       WriteLn(PServer.Address.Port);
  26.       if PChar(PServer.Data) = 'log' then
  27.         WriteLn(PChar(PServer.Data));
  28.     end;
  29.   end;


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 18:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Vielleicht hängt es damit zusammen, dass du das Paket sendest, bevor der "hörende" Socket offen ist?

Und was das Client/Server gedings betrifft: Es ist unabhängig vom Protokoll immer so, dass du einen Socket haben musst, der "hört", also der die Daten empfängt. Bei TCP ist das derjenige, der die Verbindungen aufnimmt und bei UDP halt der, der alles bekommt (weils bei UDP ja keine Verbindungen in dem Sinne gibt). Insofern ist die Bezeichnung eventuell ungeeignet. Sender und Empfänger wäre sicherlich das bessere Wortpaar.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 19:22 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Uuuuuuuhhh Broadcasting :)

Nein mit 255.255.255.255 ist es nicht getan. Um einen Broadcast über die sog. Broadcast-Adresse auszuführen, muss man die Netzadresse kennen.
Die bekommst du ganz einfach über die Netzadresse deiner IP.

Kleiner Grundkurs IP: Eine IP-Adresse besteht immer aus einem Netz-Anteil und einem Host-Anteil.

Ein Beispiel:
Es sei die IP 192.168.1.33 mit der Subnetzmaske 255.255.255.0 gegeben (Dein Rechner). (Alternative Schreibweise ist 192.168.1.33/24)
Hier ist die Netzadresse 192.168.1.0 und der Host-Teil wäre die "0.0.0.33".

Du möchtest mit einem Broadcast alle anderen Hosts in diesem Netz erreichen.
Dazu sendest du an die 192.168.1.255.

Genau diese Netzadresse (192.168.1.0) und die Broadcast-Adresse (192.168.1.255) sind reservierte Adressen, die man nicht für eigene IPs verwenden darf. Also immer die jeweils höchste und jeweils niedrigste Zahl, die durch die Netzadresse ermöglich wird.

Und nun ein Mini-Ausflug zum Thema Subnetzmasken: Alles, was in der Subnetzmaske auf 1 gesetzt ist (Bit-Ebene), gehört zur Netzadresse.
Im obigen Beispiel hat man die 255.255.255.0 als Netzmaske, was binär dann die 11111111.11111111.11111111.00000000 ist. Da sieht man, dass die ersten drei Oktette zur Netzadresse gehören und der Rest Host-Anteil ist.

und aus dem 0er-Bereich nimmst du nun einfach das höchste und schon hast du den "Host", an den du dein Zeug schicken musst, damit es alle in dem Netz bekommen :) In dem Fall also - wie oben gesagt - die 255.

Grüße,
~ Frase

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 21:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Hallo,

dann muss also, der Aufklärung zufolge, die IP ermittelt und der letzte Teil durch eine 255 ersetzt werden ? Dann kann das mit einem beliebigen Port via ResolveHost aufgelöst werden und darüber kann man dann broadcasten ?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 21:52 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Wenn du dich auf ein Klasse C Netz beschränken willst, ja. Ansonsten musst du die Subnetzmaske einkalkulieren.

Und es muss natürlich einen Socket geben, der schon auf den angegebenen Port hört, bevor du broadcastest. Sollte eigentlich klar sein :)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 17, 2009 22:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Okt 27, 2003 17:46
Beiträge: 788
Kannst auch mal im Delphi-Forum.de nach udp googln...
Die haben ein super tutorial mit komponente zu diesem thema... damit hab ich es auch bei mir realisiert ;-)

_________________
www.audi32.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mai 18, 2009 20:48 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Hi,

Dann habe ich in erster Linie die Reihenfolge vertauscht. Es muss also erst der Empfang und dann die Versendung klargemacht werden. Der Port muss dabei der selbe sein. Das macht das Programm aber nicht mit. Erzeuge ich einen Empfänger in Port 2000 und danach einen Sender ebenfalls in 2000, wird der Sender nicht mehr von SDLNet initialisiert.

Das Tutorial im Delphi-Forum kenne ich schon, nur mir gefällt die Umsetzung über SDL einfach besser.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Mai 22, 2009 12:07 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Hallo!

Ich arbeite immer noch an der Sache. Nun ist einiges schon überlegter. Es gibt zur Einfachheit zwei Programme (eins für Sender, eins für Empfänger). Ich erhalte sogar die Meldung vom Sender, ein Paket wäre erfolgreich versendet worden. Entweder wird es falsch versendet oder der Empfänger enthält noch einen Fehler, denn es kommt nicht an. Damit Ihr mal einen Überblick bekommt und selbst mal testen könnt, bei irgendwelchen Vormutungen oder Ähnlichem, im Anhang das Projekt. Man öffnet also zuerst den Empfänger (SDLUDPEmpfaenger) und danach den Sender (SDLUDPSender). Der Sender wird sich sofort wieder beenden bei Erfolg, tritt ein Fehler bei der Paketsendung auf, gibt er dazu eine Meldung aus und wartet (ReadLn). Eine Frage wäre da noch: Ist die IP welche der Sender verwendet korrekt ? Würde das überall funktionieren ? Das ist an sich meine Netzwerk-IP, bloß der letzte Teil durch 255 ersetzt. Ich habe übrigens viel mit der Dokumentation gearbeitet, vieles leitet sich daraus auch ab - leider nicht alles.

Selbstverständlich hier die relevanten Codeabschnitte, ich weiß selbst, wie nervig es sein kann, Projekte zu ziehen und offline anzuschauen. Lustigerweise entsprechen die relevanten Teile fast komplett den Codedateien, ich lasse daher nur Grundlagen weg. (Das ist auch ein guter Grund dafür, Sender und Empfänger zu trennen, da die Codes sehr klein und überschaubar werden.) Welche Codebox für welches Programm steht zeigt die erste Zeile der jeweiligen Codes.
Code:
  1. var Empfaenger  : PUDPSocket; // Sockets für Empfang und Sendung von Daten
  2.     PEmpfaenger : PUDPPacket; // Datenpakete für Empfang und Sendung von Daten
  3. begin  
  4.   Empfaenger := SDLNet_UDP_Open(0);       // Socket zum Paketempfang initialisieren
  5.   PEmpfaenger := SDLNet_AllocPacket(512); // Platz für das eingehende Paket reservieren
  6.   // Hauptthread
  7.   while not False do
  8.   begin
  9.     // Eingehende Netzwerkdaten verarbeiten
  10.     if SDLNet_UDP_Recv(Empfaenger, PEmpfaenger) = 1 then
  11.       if PChar(PEmpfaenger.Data) = PChar('log') then
  12.         WriteLn(PChar(PEmpfaenger.Data))
  13.       else if PChar(PEmpfaenger.Data) = '' then
  14.         WriteLn('a')
  15.       else
  16.         WriteLn(PChar(PEmpfaenger.Data));
  17.   end;


Code:
  1. var Sender  : PUDPSocket; // Sockets für Empfang und Sendung von Daten
  2.     PSender : PUDPPacket; // Datenpakete für Empfang und Sendung von Daten
  3.     IP      : TIPAddress; // Broadcast-IP im Netzwerk //! Diese Variable nötig ?
  4. begin
  5.   Sender  := SDLNet_UDP_Open(0);      // Socket für Paketsendung öffnen
  6.   PSender := SDLNet_AllocPacket(512); // Platz für das zu sendende Paket reservieren
  7.   // Paket abfertigen und rausschicken.
  8.   SDLNet_ResolveHost(IP, '192.168.69.255', 0);
  9.   PSender.Address.Host := IP.Host;
  10.   PSender.Address.Port := IP.Port;
  11.   PSender.Data         := PUInt8(PChar('log'));
  12.   PSender.Len          := Succ(Length(PChar(PSender.Data))); // Ohne Datenlänge wird nichts gesendet
  13.   if SDLNet_UDP_Send(Sender, -1, PSender) = 0 then
  14.   begin
  15.     WriteLn('Es konnte kein Paket versendet werden.');
  16.     ReadLn;
  17.   end;

Gruß
Nils


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 23, 2009 17:01 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Hast du eigentlich überhaupt schon mal ein Paket erfolgreich versendet? Weil ich schaff es mit deinem Code als Basis nichtmal ein Packet an eine feste IP zu senden. Natürlich kenn ich mich mit SDL auch überhaupt nicht aus.
Zumindest könnte man so schonmal eine falsche Adresse für den Broadcast ausschließen.

Edit:
Ok, ich glaub ich hab jetzt einen Durchbruch erlebt.
Man muss beim Empfänger in der Zeile "Empfaenger := SDLNet_UDP_Open(0);" die NULL durch eine richtige Portzahl ersetzen, d.h. größer NULL.
Und im Sender bei "SDLNet_ResolveHost(IP, '192.168.69.255', 0);" die NULL natürlich auch durch die selbe Zahl.
Die NULL steht für einen zufälligen Port. Siehe http://gpwiki.org/index.php/SDL:Tutorial:Using_SDL_net
Außerdem sind einige Ports auch reserviert, z.B. 80 für HTTP.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 23, 2009 19:36 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Soweit ich weiß sind die Ports von 1-1023 fest zugewiesen, alles von 1024-49151 für Nebenstellen reserviert. Daher habe ich einfach mal 49152 genommen. Lässt man nun den Empfänger laufen und den Sender senden, tritt OHNE Debugger von Delphi sofort beim Sender eine Exception auf, MIT Debugger jedoch NICHT. Das kann ich mir nicht erklären. Dies passiert bei Port 0 seltsamerweise nicht. Das wäre ja ein Hinweis darauf, dass der Port doch reserviert ist und es daher irgendwelche Überschneidungen gibt. Aber welchen Port soll ich dann nehmen ?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 23, 2009 20:58 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Ja, den Fehler hatte ich auch. Ist natürlich nicht so gut, wenn man nichtmal prüfen kann wo der Fehler auftritt.
Ich hab' grade noch bischen probiert und glaube der Fehler tritt auf wenn Sender und Empfänger den selben Port haben. Wenn man den Sender startet ohne Empfänger gehts und wenn 2 mal der Empfänger gestartet wird kommt auch der Fehler.

Ich denke das Problem tritt auf wenn 2 "Server" den selben Port benutzen wollen. Ist das selbe bei den Indy-Komponenten die ich immer verwende, wie ich grade festgestellt habe. Allerdings gibt es da eine Unterteilung in Server und Client. Das ist bei SDL wohl nicht der Fall, sodass immer ein Server und Client erzeugt wird. Und 2 Server geht wie gesagt nicht.

Also vielleicht gibt es noch eine andere Möglichkeit die Sockets zu benutzen, ansonsten einfach die Ports bei Sender und Empfänger unterschiedlich wählen, ist ja kein Problem.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mai 23, 2009 23:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Eh. Also nochmal kurz was zum Thema IP im allgemeinen. Es kann immer nur ein Socket auf einem Port hören. Also Pakete dort empfangen. Daher kann man nur einen Server mit der gleichen Portnummer erzeugen. Die Ports 1 bis 1024 sind für "ernsthafte" Anwendungen (Apache (80 und 443), Mail (993 und ne menge andere) ...) reserviert und unter Linux braucht man auch Admin-Rechte um darauf einen Socket zu erzeugen.
Port 0 gibt es nicht. Dies ist ein Pseudo-Port der dann in einen beliebigen, gerade freien Port umgewandelt wird. Bei UDP gibt es keine Server und Clienten in dem Sinne. Es gibt nur Sockets. Und jeder Socket kann senden und Empfangen. Daher bleibt dir nur, zwei verschiedene Ports zu nehmen, solange du das ganze auf einem Rechner ausprobierst. Bei zwei verschiedenen PCs kannst du ohne probleme zwei gleiche Ports nehmen. Was du aber auch tun kannst, wenn du nur Datenverkehr in eine Richtung brauchst oder ihn zumindest so initiieren kannst, dass erstmal nur in eine Richtung geschickt wird, ist, dass du einen Socket als "Server" (mit absicht in Anführungszeichen, denn Server gibt es bei UDP nicht direkt - aber du kannst selber einen bauen, wie folgt) öffnest. Dieser wird auf einem festen Port (meinetwegen 49567) geöffnet. Dann beginnt er zu "hören" und wartet auf Pakete. Die "Clienten" öffnen nun einen Socket aufm Pseudoport 0, der sich ja automatisch in einen gerade zur verfügung stehenden Port umwandelt. Dann senden sie ein Paket an den Server, der dadurch auch die Portnummer des Clienten erfährt und du kannst zumindest sporadisch eine Datenübertragung beginnen.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 24, 2009 11:21 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Irgendetwas stimmt hier nicht. Denn wenn ich Empfänger und Sender auf 0 öffne, hätten beide einen freien Port. Da es ein Broadcast ist, wäre das kein Problem - so wie ich es jetzt verstanden habe. Aber dann kommt nichts beim Empfänger an. Denn wozu dem Empfänger einen festen Port verpassen. Wäre doch viel einfach beiden einen freien zu geben. Falls ich gerade Mist gelabert habe, gibt es noch üble Verstädnisprobleme. Und ich gehe mal schwer davon aus, dass das gerade totaler Humbuk war. Dann erklärt sich wenigstens, warum es bei beiden 0er Ports keinen Ärger gibt, da sie beide einen unterschiedlichen hätten. Nur die Frage, warum nichts stellt sich dann noch. Oder ich laber nur Stuss.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 24, 2009 12:29 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
Ich glaube der Broadcast schickt die Daten an alle Computer im Netzwerk, aber nur an einen Port. Wenn der Empfänger auf einem anderen Port "hört" kommen sie auch nicht an. Das wäre ja auch merkwürdig weil dann alle Programme die sonst noch laufen irgendwelchen, für sie unverständlichen Kram, zugesendet bekommen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mai 24, 2009 14:40 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Zwei an einem Rechner ist eigentlich sinnlos. An zwei Rechnern mit dem selben Port gibt es logischerweise keine Exception mehr, aber es kommt trotzdem nichts beim Empfänger an.

Fragt mich bloß nicht warum, aber wenn ich den Port 50000 nehme läuft alles. Wäre schön, wenn mir noch einer sagen könnte, warum der Port 49152 nicht läuft. Es liegt offensichtlich am Port.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 26 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.011s | 15 Queries | GZIP : On ]