Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Es kann auch sein, dass eine Anwendung den Port 4...irgendwas gerade blockiert. Irgendwelche Dinge benutzen ja auch Ports, bist ja nicht der einzige.
Aber wie Schläfer sagt, Broadcasts sind immer an einen Port gebunden. Und wenn du den Empfänger auf Port 0 erzeugst, weisst du ja nicht, an welchen Port du schicken musst. Denn an Port 0 kannst du nicht schicken.
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 network • my 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
Ja, dann ist wohl unbedingt noch eine Einstellungsmöglichkeit nötig. Denn wer weiß denn, ob der Port 50000 woanders auch frei ist. Soweit funktioniert nun das Senden und Empfangen. Nur eine Sache ist mir bei der weiteren Programmierung aufgefallen: Wenn ich nun einen Broadcast sende, schicke ich ihn dummerweise auch an mich. Also antworte ich auch auf den Broadcast, was totaler Unfug ist. Daher wollte ich natürlich eine If einbauen, die mir ermöglicht, zu überprüfen, ob der Broadcast von mir gesendet wurde oder nicht. Jedes Paket enthält die Absender-IP, die ließe sich dann mit der IP des Empfangspakets vergleichen. Leider sind die beiden IPs NICHT identisch. Und ich habe extra darauf geachtet, dass in keiner Weise auf dem Port von irgendwoher eine Störung kommt. (Zum Verständis: Sender und Empfänger befinden sich nun in einem Programm). Die Zahlen unterscheiden sich extrem, die eine IP hat zum Beispiel zweimal eine 4, die andere nur einmal. Es sind also tatsächlich andere IPs (und nicht irgendwie verdreht). Wenn man direkt nach der Initialisierung (Reservierung des Speichers) des Empfängerpakets die dort automatisch eingetragene IP ausgibt, erhält man wieder eine komplett andere, die mit keiner der beiden ungleichen IPs in irgendeiner Form was zu tun hat. Schlussfolgerung: Die IPs werden in gewissen Abständen neu generiert, aber offensichtlich nach einem festen System, da sie immer gleich sind. Habt Ihr irgendeine Idee, woran das liegen könnte ? Ich glaube kaum, dass es an SDL_net liegt, es stinkt eher nach einer UDP-Vorgehensweise die ich nicht kenne. In der Dokumentation von SDL_net steht ein Hinweis:
Zitat:
Note that the local and remote channel numbers do not have to, and probably won't, match, as they are only local settings, they are not sent in the packet.
Dies bezieht sich auf das Emfpangskommando (SDLNET_UDP_Recv). Das sagt zwar nichts direkt über den Host aus, aber könnte es nicht auch damit was zu tun haben ? Dass einfach die eine IP lokal im Programm eine andere ist (warum auch immer) als woanders ?
Ich glaube zwar kaum, dass es was bringt, aber hier nochmal der Code. Vielleicht bin ich auch einfach nur blind. Was mir übrigens durch reines Testen aufgefallen ist: SDLNet_ResolveHost (Zeile 24) weist auf die Variable IP einen Host und einen Port zu (Host in Cardinal, Port in Word). Wenn man nun direkt nach der Zuweisung den Port per Hand auf 50000 setzt, kann das Programm nichts mehr empfangen. Lässt man sich danach jedoch Port mal ausgeben, kommt in beiden Fällen (also einmal ohne explizite Zuweisung, ein anderes Mal mit) 20675 raus. Ist unwahrscheinlich, dass das was mit dem Problem zu tun hat, aber seltsam ist es trotzdem.
Code:
program SDLUDPEmpfaenger;
{$APPTYPE CONSOLE}
uses
SDL, SDLNet, SysUtils;
const Port =50000;
var// Netzwerk
Socket : PUDPSocket;// Sockets für Empfang und Sendung von Daten
PEmpfaenger : PUDPPacket;// Datenpakete für Empfang und Sendung von Daten
PSender : PUDPPacket;
IP : TIPAddress;// Broadcast-IP im Netzwerk //! Diese Variable nötig ?
begin
SDL_Init(SDL_INIT_VIDEO);// SDL initialisieren
SDLNet_Init;// Nertzwerkkomponente initialisieren
Socket := SDLNet_UDP_Open(Port);// Socket zum Paketempfang initialisieren
PEmpfaenger := SDLNet_AllocPacket(512);// Platz für das eingehende Paket reservieren
PSender := SDLNet_AllocPacket(512);// Platz für das zu sendende Paket reservieren
SDLNet_ResolveHost(IP,'192.168.69.255', Port);
PSender.Address.Host:= IP.Host;
PSender.Address.Port:= IP.Port;
PSender.Data:= PUInt8(PChar('knock'));
PSender.Len:=Succ(Length(PChar(PSender.Data)));// Ohne Datenlänge wird nichts gesendet
SDLNet_UDP_Send(Socket,-1, PSender);
// Hauptthread
whilenotFalsedo
begin
// Eingehende Netzwerkdaten verarbeiten
if SDLNet_UDP_Recv(Socket, PEmpfaenger)=1then
begin
WriteLn(FloatToStr(PEmpfaenger.Address.Host)+' :: '+FloatToStr(PEmpfaenger.Address.Port));// Wesentlich sinnvoller als die If-Bedingung
WriteLn(FloatToStr(PSender.Address.Host)+' :: '+FloatToStr(PSender.Address.Port));// Wesentlich sinnvoller als die If-Bedingung
end;
end;
// Programmende, alles freigeben.
SDLNet_FreePacket(PEmpfaenger);
SDLNet_Quit;
SDL_Quit;
end.
Auf jeden Fall erstmal an dieser Stelle ein dickes Dankeschön dafür, dass Ihr so schön geholfen habt!
Die Antwort auf deine Frage ist einigermaßen trivial.
"192.168.69.255" ist die IP an die gesendet wird und die in PSender.Address.Host drin steht.
"192.168.69.x" (wobei x die letzte Zahl deiner wirklichen IP ist, die ich ja nicht kenne) ist die Adresse von der das Paket kommt. Ganz sicher ist aber das sie keine 255 am Ende hat und somit verschieden sein muss.
Das nach der Reservierung des Speichers dort wieder etwas anderes drin steht, liegt wohl einfach daran das es NICHT initialisiert ist und somit bestenfalls Kauderwelsch drin steht.
Soviel zum IP-Adressenvergleich. Dann zum Port:
Ein Blick auf http://sdl.beuc.net/sdl.wiki/IPaddress verrät das die IP und der Port in "Network Byte Order" gespeichert sind.
Ok wusste ich jetzt auch nicht was das zu bedeuten hat und ein Überfliegen der Wikipedia hat auch nichts gebracht, aber mit ein bischen Probieren kommt man auf die Lösung.
50000 ist als Hexadezimal-Zahl "C350", vom Windows-Rechner umgerechnet. "50" ist Dezimal die 80 und "C3" die 195.
80*256+195=20675
Zugegeben das kann man auch ohne Taschenrechner rausbekommen. Aber was ich damit eigentlich meine, ist dass die Byte-Reihenfolge vertauscht ist. Auch bei der IP, falls du die zurückrechnen möchtest. Allerdings ist die Reihenfolge der Bits im Byte gleich, was es auch einfacher macht damit zu rechnen.
Edit: Dir sind vielleicht die Begriffe "Big-endian" und "Little-endian" geläufig. Laut Wikipedia wird beim IP die "Big"-Variante verwendet.
Ah, dann steht also in IP.Host die 192.168.69.255 (in Network-Byte-Order) und stimmt daher nicht überein mit der eigentlichen IP. Nur wie kriegt man jetzt überhaupt die eigene IP raus ? Dafür finde ich keine Funktion und über WinSock o.ä. was zu machen halte ich für sinnlos, da dann der ganze Zweck von SDL wegfallen würde.
Zu den Ports: Danke für die Aufklärung, aber das erklärt noch nicht, warum der Port beim direkten Setzen nicht übereinstimmt, ansonsten schon. Da in beiden Fällen die Network-Byte-Order drinnensteht, dürfte das eigentlich kein Problem sein. Aber ich denke das ist auch nicht so wichtig, hat mich bloß mal interessiert.
Eine Funktion, die die eigene IP ausgibt hab ich auch nicht gefunden. Dazu bräuchte man auch noch den Namen des Netzwerks oder der Verbindung, weil man ja auch mehrere Netzwerkkarten haben kann, wenn ich das richtig verstanden habe.
Eventuell kann man das Problem aber umschiffen.
Wenn ich als Zieladresse "255.255.255.255" nehme kommt zumindest am selben Computer was an, ohne das man auch nur einen Teil der IP wissen muss. Ich schätze mal damit wird quasi an alle Computer in allen Netzen gesendet. Vom Router wird das angeblich rausgefiltert, damit es nicht ins Internet rausgeht, oder so ähnlich.
Der Trick ist jetzt einfach das man einen Port öffnet der nur beim Sender vorhanden ist, somit sollten die Empfänger auf ihrem Port nichts empfangen. Der Sinn davon ist das man anhand des Absenders die eigene IP rausbekommt, da es nur eine mögliche Quelle geben sollte.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ja, der Router dürfte das nicht ans Internet weiterleiten. Aber trotzdem gehts natürlich einmal durchs lokale Netzwerk. Fürs rausfinden der IP vielleicht etwas oversized. Daher würde ich sagen, dass du generell auf 255.255.255.255 aufsetzen solltest für den Broadcast (btw, schau mal nach TTL (Time-To-Live) werten). Du musst dann deine IP nicht kennen und du hast den vorteil, dass es über *alle* Netzwerkkarten rausgeht. Wenn also auch ein Rechner mehrere installiert hat (beispielsweise den Hamachi-Adapter oder VirtualBox-Geräte), ist das auch hilfreich. Dann solltest du theoretisch auch mehrere Pakete zurückbekommen...
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 network • my 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
Moin, ich verstehe ja, was Du willst, aber wie soll man das wieder realisieren ? Denn wenn mir die nicht SDLNet zur Verfügung stellt, steckt man doch tief in der Scheiße oder gibt es andere Varianten diese zu bekommen ?
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Wofür brauchst du denn deine eigene IP?
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 network • my 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
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Achso, das habe ich falsch verstanden. Hmm... Soweit ich das sehen kann, wird das etwas schwieriger. Auf die schnelle habe ich mit google nur das hier auftreiben können msg00642.html.
Scheint so, als ob SDL sowas noch nicht kann.
Ich bin sowieso der Ansicht, dass SDL_Net ziehmlich beschränkt ist und das ein oder andere wirklich blöde Manko hat (bspw. keine Non-Blocking Funktion um die Anzahl der zur Abholung bereitstehenden Bytes abzufragen), weshalb ich auf Synapse umgestiegen bin. Vielleicht willst du dir das mal anschauen? Ansonsten musst du wohl oder übel in den Mailing-List-Post von oben schauen und rausfinden, ob du damit was anstellen kannst.
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 network • my 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
Die letzte Nachricht hier ist schon einige Zeit her, ich habe weder was geschrieben noch mich bedankt. Zur Zeit habe ich einiges um die Ohren und kann wahrscheinlich erst bald was tun und schaue mir dann Synapse an. In dem Sinne: Danke für Eure bisherige Hilfe in diesem Thema!
Mitglieder in diesem Forum: Google [Bot] und 11 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.