Guybrush Threepwood Geschrieben 7. März 2003 Geschrieben 7. März 2003 Hi, ich spiele mit dem Gedanken ein Chatprogramm zu programmieren. Dabei soll es sich um einen Server handeln der die Nachrichten empfängt und an alle Benutzer weiterleitet und um einen Client der beim Benutzer läuft, die Nachrichten an den Server sendet und die Nachrichten der anderen Benutzer vom Server empfängt und anzeigt. Das ganze soll über Windows Sockets laufen. Ich bin jetzt am Überlegen ob ich für das Senden und Empfangen jeweils einen Thread anlege oder auch beides in einem möglich ist. Was würde z.B. passieren wenn Server und Client gleichzeitig senden und sich alles in einem Thread befindet? Würde ein anschließender recv() aufruf die Daten trotzdem einwandfrei empfangen? Gruß Guybrush Zitieren
SgtBadAzz Geschrieben 8. März 2003 Geschrieben 8. März 2003 Originally posted by Guybrush Threepwood Hi, Das ganze soll über Windows Sockets laufen. Ich bin jetzt am Überlegen ob ich für das Senden und Empfangen jeweils einen Thread anlege oder auch beides in einem möglich ist. Was würde z.B. passieren wenn Server und Client gleichzeitig senden und sich alles in einem Thread befindet? Würde ein anschließender recv() aufruf die Daten trotzdem einwandfrei empfangen? Gruß Guybrush Ich würde es wie bei FTP machen, ein Port wird abgehört, wenn da was reinkommt wird dem Client mitgeteilt über welchen Port die zukünftige Kommunikation laufen soll und pro Verbindung ein Thread und ein dedizierter Port. Frank Zitieren
Guybrush Threepwood Geschrieben 10. März 2003 Autor Geschrieben 10. März 2003 Danke, das ist ne gute Idee. Das löst direkt schon ein paar Probleme die mir auch noch eingefallen waren. Gruß Guybrush Zitieren
Guybrush Threepwood Geschrieben 21. März 2003 Autor Geschrieben 21. März 2003 Kann es eigentlich sein das Daten irgendwie untergehen wenn zuviele direkt hintereinander über den selben Port gesendet werden? Ich hab nämlich ne Funktion eingebaut das der Server sich die letzten 100 Nachrichten merkt und wenn jemand in den Chat eintritt, er diese 100 Nachrichten gesendet bekommt. Nur komischerweise kommen die Nachrichten teils garnicht, oder in verkehrter Reihenfolge an. Ich hab dann versucht nach jedem send() ein Sleep() zu setzten, das hat aber auch nur ein bischen geholfen. Hat irgendwer ne Idee woran das liegt? Fehler treten nämlich auf beiden Seite nicht auf.:confused: Zitieren
PuppetMaster Geschrieben 21. März 2003 Geschrieben 21. März 2003 Versuch doch die mitgespeicherten Zeilen in einen String zu kopieren und diese zu senden, vielleicht brauchst du dann gar nicht mehr die letzten 100 Zeilen einzeln zu senden??? :marine Zitieren
Guybrush Threepwood Geschrieben 21. März 2003 Autor Geschrieben 21. März 2003 Ja, das wär natürlich auch ne Möglichkeit. Danke! Aber warum die Nachrichte teilweise nicht ankommen würde mich trotzdem mal interressieren. Zitieren
Klotzkopp Geschrieben 21. März 2003 Geschrieben 21. März 2003 Verwendest du TCP (SOCK_STREAM) oder UDP (SOCK_DATAGRAM)? Zitieren
Guybrush Threepwood Geschrieben 21. März 2003 Autor Geschrieben 21. März 2003 Also in der Funktion socket() habe ich das Flag SOCK_STREAM angegeben. Zitieren
Klotzkopp Geschrieben 21. März 2003 Geschrieben 21. März 2003 Dann machst du selbst beim Empfangen oder Senden etwas falsch. Die eingebaute Fehlerkorrektur bei TCP sorgt dafür, dass nichts verloren geht und die Reihenfolge stimmt. Da es relativ schwierig ist, beim Senden etwas falsch zu machen , tippe ich mal darauf, dass beim Emfang was nicht stimmt. Zitieren
Guybrush Threepwood Geschrieben 21. März 2003 Autor Geschrieben 21. März 2003 ich wüßte nicht was falsch sein könnte, im Client hab ich in einen 2.Thread eine Schleife in der folgendes recv() sitzt: recv(CliSocket,szText,501,0); und im Server hab ich halt für jede Verbindung einen Thread mit Schleife wo folgendermaßen gesendet wird: send(ChatSocket[nPort],szText,strlen(szText)+1,MSG_DONTROUTE) Zitieren
Klotzkopp Geschrieben 21. März 2003 Geschrieben 21. März 2003 Die Frage ist: was machst du nach dem recv? Berücksichtigst du, dass mehr als ein nullterminierter String in dem Puffer stehen kann? Zitieren
Guybrush Threepwood Geschrieben 21. März 2003 Autor Geschrieben 21. März 2003 Heißt das das mit einem recv() Aufruf auch die Daten von 2 oder mehreren send() Aufrufen empfangen werden kann? Zitieren
Klotzkopp Geschrieben 21. März 2003 Geschrieben 21. März 2003 Es gibt keine 1-zu-1-Beziehung zwischen send und recv, das sind reine Byteströme. Dein recv wird AFAIK erst dann zurückkommen, wenn die 501 Bytes voll sind. Natürlich können dann mehrere Strings drinstehen. Und der letzte String im Puffer ist mit ziemlicher Sicherheit nicht vollständig. Zitieren
Guybrush Threepwood Geschrieben 21. März 2003 Autor Geschrieben 21. März 2003 Das würde aber doch dann bedeuten wenn ich bei recv max. 500 Bytes erwarte, aber nur 50 sende und dann nichts mehr, dass recv nicht weitermachen würde und das ganze Programm an der Stelle stehen bleibt, oder nicht? Zitieren
Guybrush Threepwood Geschrieben 21. März 2003 Autor Geschrieben 21. März 2003 Das ist bei mir aber nicht so:confused: Wenn der Client gestartet wird, sendet er einen String mit dem Namen und dem Passwort des benutzers an den Server, dieser String ist ca. 10- 20 Byte lang. Der Server erwartet einen max. 100 Byte String und macht trotzdem weiter. Danach wird nämlich der String mit einer Textdatei verglichen und dann ein freier Port gesucht. Zitieren
Klotzkopp Geschrieben 21. März 2003 Geschrieben 21. März 2003 Originally posted by Guybrush Threepwood Das ist bei mir aber nicht so:confused: Stimmt, weiß auch nicht, wie ich darauf gekommen bin. Ich hatte irgendwie in Erinnerung, dass recv blockt, bis der Puffer voll ist. War wohl nun ein Traum... Zitieren
nic_power Geschrieben 21. März 2003 Geschrieben 21. März 2003 Hallo, recv() blockiert solange, bis Daten auf dem Socket anliegen. Diese Daten werden dann (bis zur maximalen Länge) gelesen und zurückgeliefert. Optional kannst Du den Socket noch auf nonblocking schalten; in dem Fall kehrt recv() auch dann zurück, wenn keine Daten anliegen. Nic Zitieren
Guybrush Threepwood Geschrieben 24. März 2003 Autor Geschrieben 24. März 2003 Wo könnten die Daten den am wahrscheinlichsten verloren gehen? Im Netzwerk, weil sie evtl. durch die schnell aufeinanderfolgende Masse überschrieben werden oder in meinem Client wenn er sie per SendMessage() an die Listbox sendet damit diese sie anzeigt? Zitieren
nic_power Geschrieben 24. März 2003 Geschrieben 24. März 2003 Hallo, Verloren gehen können die Daten eigentlich nur, wenn Du UDP verwendest. TCP hat eine Flußkontrolle. Entweder beim Empfang geht etwas schief, oder Du fragst beim Senden die Returnwerte nicht richtig ab (d.h. Du bekommst es nicht mit, wenn das Senden fehlschlägt, weil beispielsweise ein Puffer beim Empfänger voll gelaufen ist). Nic Zitieren
Guybrush Threepwood Geschrieben 25. März 2003 Autor Geschrieben 25. März 2003 Also ich frage bei jedem send bzw. recv ab ob der Returnwert gleich SOCKET_ERROR ist und wenn ja lass ich mir eine Fehlermeldung samt Fehlercode ausgeben. Es tritt aber nirgendwo ein Fehler auf. Ich habe mir jetzt mal alles ausgeben lassen was der Server sendet, um zu sehen ob vielleicht ein Logikfehler drinsteckt, es wird aber alles gesendet. Als ich dann beim Client eine Messagebox eingebaut habe die mir immer das anzeigt was von recv geholt wurde, kahmen nur noch ca. 6 Nachrichten von ca. 40 an. Das bestätigt doch den Verdacht das zu viel gesendet wird das zu langsam vom socket geholt wird, oder nicht? Zitieren
Klotzkopp Geschrieben 25. März 2003 Geschrieben 25. März 2003 Prüf doch mal, ob die Anzahl der empfangenen Zeichen zur Anzahl der ausgegebenen Zeichen passt. Zitieren
Guybrush Threepwood Geschrieben 25. März 2003 Autor Geschrieben 25. März 2003 Hab`s gerade überprüft und er liefert mehr Zeichen zurück. Du hattest also Recht damit, dass mehrere Nullterminierte Strings zurückgeliefert werden. Nur wie komme ich da am besten dran? Funktionen wie strtok() stoppen ja beim '\0'. Muss ich mir da selber was schreiben, oder gibst da doch irgendeine Funktion? Zitieren
Klotzkopp Geschrieben 25. März 2003 Geschrieben 25. März 2003 Soweit ich weiß, gibt es da keine Funktion. Entweder suchst du nach dem Nullzeichen weiter, falls noch nicht alle empfangenen Bytes verarbeitet wurden, oder du nimmst ein anderes Trennzeichen. Oder du entwickest ein eigenes "Protokoll", mit einem Header, in dem steht, wie lang der nachfolgende String ist. Dann brauchst du gar kein Trennzeichen mehr. Zitieren
Guybrush Threepwood Geschrieben 25. März 2003 Autor Geschrieben 25. März 2003 Ich könnte doch auch einfach einen Zeiger auf das erste Zeichen setzen und den solange erhöhen wie Zeichen empfangen wurden und jedesmal wenn ein '\0' kommt wechsle ich die Variable. Das müßte doch klappen oder siehst du da irgendwelche Probleme? Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.