Einzelnen Beitrag anzeigen

Muetze1
(Gast)

n/a Beiträge
 
#5

Re: Client/Serververbindung arbeitet kurz und friert dann ei

  Alt 19. Jul 2006, 12:27
Zitat von BlackJack:
Wie ist das denn, wenn ich im OnRead-Event sagen wir 50 byte gesendet bekomme (das kann ich doch über Socket.ReceiveLength erfahren, oder?), aber nur 30 Bytes über Socket.ReceiveBuffer aus dem Socket auslese. wenn dann wieder ein OnRead-Event auftritt, stehen dann "vorne im Socket" noch die restlichen 20 Byte vom vorherigen Event?
Ja.

Zitat von BlackJack:
Oder umgekehrt, wenn ich 20 bytes im OnRead bekomme, aber 50 bytes aus dem Socket auslesen will, und während des Auslesens (also während ich noch auf die restlichen 30 byte warte) wird ein weiterer OnRead-Event ausgelöst. kann es dann sein dass der Event mit einem "leeren" Socket ausgeführt wird, weil ich die zugehörigen 30 bytes ja schon ausgelesen habe? weil das kommt bei mir auch manchmal vor, dass OnRead ausgeführt wird, aber Socket.ReceiveLength = 0 ist.
Ja. Da dein Code wartet bis die Receivelength stimmt (polling) aber der Socket mit Ereignisssteuerung arbeitet, teilt er dir durch erneutes aufrufen des OnRead mit. Da liegt auch dein Problem begraben. Dieser Aufruf wird vom Thread des Sockets ausgelöst und wird im Haupt VCL Thread Synchronisiert. Dieser hängt im Normalfall in deinem OnRead, weshalb er nicht zu Zuge kommt. Da du aber ein Sleep() drinne hast, gibst du Rechenzeit ab - u.a. an den VCL Thread, der dann dein OnRead erneut auslöst. Deine OnRead Methode wiederrum ist aber nicht reentrant ausgelegt und es kommt zu dem Problem wie von dir beschrieben.

Zitat von BlackJack:
und ich weiss nicht genau wie ich das Onwrite benutzen soll (OnRead benutz ich ja schon). wird dieser Event nicht immer dann ausgelöst, wenn ich was mit socket.SendText/Buffer sende?
Vom Namen her schon, klar - aber im NonBlocking Mode der Sockets (d.h. sie benutzen einen Thread), wird dieses Event soweit nicht ausgelöst. Ich habe dieses Event bisher auch noch nie gebraucht.

Zitat von BlackJack:
und ob ich jetzt SendText oder SendBuffer benutze sollte doch letztendlich egal sein, oder? nur dass man beim ReceiveBuffer noch angeben kann, wie viele Bytes er auslesen soll (und das ist ja wohl wichtig, wenn ich eben nicht wissen kann, ob die Nachrichten "vermischt" ankommen).
Der Buffer des Sockets ist es wurscht welche Daten in ihm liegen. Es ist ihm auch egal wie sie hineinkommen. SendBuf und SendText sind nur zwei Methoden für unterschiedliche Datentypen und somit nicht anders von der Funktionalität. Bei ReceiveText und ReceiveBuf() ist es entsprechend.

Die Sockets haben einen kleinen und begrenzten Buffer. Daher ist es nicht ratsam wissentlich Daten in einem OnRead nicht komplett auszulesen und zu warten bis die benötigte Menge an Daten empfangen ist. Es empfiehlt sich lieber einen Buffer selber an zu legen, alle Daten vom Socket in den Buffer zu schreiben (bzw. anzuhängen) und dann von vorne den Buffer durchgehen, interpretieren und schauen ob man genug empfangen hat. Dieser Teil kann immer nach einem erfolgtem OnRead ausgeführt werden. Nach erfolgreicher Interpretation einfach den Teil vorne vom Buffer entfernen. Ich habe dazu immer einen TMemoryStream verwendet und es klappte soweit alles recht gut. Beim Server muss man dann natürlich einen MemoryStream pro Client vorhalten. Ein grundlegendes Beispiel dazu könnte man sich in dem Chat auf meiner HP anschauen.
  Mit Zitat antworten Zitat