PB-NetworkServer/unverständliches Verhalten!?

Fragen und Bugreports zur PureBasic 4.0-Beta.
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Vielleicht nicht ganz richtig ausgedrückt.
Wenn ein Sendeauftrag intern auf verschiedene Pakete aufgeteilt werden kommen diese natürlich in der richtigen Reihenfolge wieder an.
Bei vielen Sendeaufträge (Asynchron) sollte man dieses besser prüfen aus den von mir beschriebenen gründen.


FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Ich bin mir sicher, das es nun ein Bug ist bzw. eine falsch geplante Struktur von Fred / PB. Ich habe zum testen nicht nur mal die zu senden Daten von 10 Zeichen auf 10 Millionen ZEichen je Verbindung erhöht (was angeblich immer noch gesendet wurde), sondern zusätzlich direkt nach dem sendnetwork() mal

Code: Alles auswählen

Debug "SendNetworkString: " + Str( SendNetworkString(ClientID, "fdsdfrwer") )
eingefügt.
Und Sie da, sendnetworkdata() sagt es wurden daten gesendet, sendnetworkstring() sagt es kam zu einem fehler (was ja korrekt ist).
Also funktioniert da absolut was nicht :-(
Ich denke, da muß Fred noch mal einiges Überprüfen. Kein wunder das ich letztes Jahr aufgegeben habe weil ich einfach nicht nachvollziehen konnte wieso ständig Daten nicht ankamen obwohl sie angeblich gesendet wurden. hmmm.

[edit]
wollte für die Antwort auf Christis Beitrag (folgt auf diesen) nicht extra einen Eintrag verschwenden :-)
Ich selber finde PB trotz dem "vermuteten Bug" weiterhin Klasse. Es scheint bisher nur noch keiner bemerkt zu haben, also konnte der Fehler auch noch nicht behoben werden. Es ist auch kein kritischer Fehler, wenn auch ein recht großer. Aber er löst wenigstens keine Katastrophen aus, wenn man es weiß. Ärgerlich bleibt es aber trotzdem, wenn wegen solcher Dinge konnte ich bisher noch kein einziges PRogramm in PB fertig erstellen, weil es immer wieder Dinge dieser Art gab, die es VORLÄUFIG für mich nicht sinnvoll machten weiter zu programmieren. Aber PB finde ich wie schon gesagt trotzdem gut.
Hoffe nur, das vom PB-TEAM mal dazu Stellung nimmt.
Zuletzt geändert von Toshy am 08.01.2007 22:08, insgesamt 1-mal geändert.
1. Win10
PB6.1
Christi
Beiträge: 154
Registriert: 31.08.2004 14:17
Kontaktdaten:

Beitrag von Christi »

scheiß buggy purebasic ! is doch echt zum kotzen auf nichts kann man sich verlassen ! und ja ich bin grad schlecht gelaunt und ja ihr könnt euch nen dummen spruch sparn !
Benutzeravatar
FGK
Beiträge: 249
Registriert: 09.01.2005 14:02
Computerausstattung: i5-4430 CPU / 8GB RAM
GeForce GT630
Windows 10 Home / 64-bit
Wohnort: Augsburg

Beitrag von FGK »

Nein mein lieber Christi den dummen Spruch kann ICH mir sicher nicht
ersparen. Immerhin ist es schon der 2. Post von dir heute der
Purebasic als nicht akzeptabel darstellt und wie "schlecht" es doch sei.
Mal ehrlich wenn dir die Sprache nicht passt oder dir zu "buggy"
ist dann laß es halt sein und such dir ne andere Sprache die "perfekter"
zu dir paßt und hör auf hier rumzumaulen.
Das du heute sauer bist ist mir auch ehrlich gesagt einerlei und
rechtfertigt deine Äußerungen nicht unbedingt!

Und zum Schluß noch ein Zitat aus ts-softs Signatur die auch hier gut
passen würd

Wenn der Bauer nicht schwimmen kann, liegt es immer an der Badehose

in diesem Sinne

FGK
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Beitrag von freak »

  • "Connect" events werden vorrangig bearbeitet:
    Das ist war. Es macht auch aus algorithmischer Sicht Sinn, denn das connect ist
    ein event des Servers selbst, wobei alles andere Events auf den vom Server verwalteten
    Clients sind. Es macht also Sinn zuerst auf eine neue Verbindung zu prüfen,
    bevor man die Liste der Clients durchläuft um nach Events zu suchen.
    (wozu erst die ganze Liste der Clients durchlaufen, wenn man doch mit einem einzigen Check
    schon feststellen kann ob es bereits einen Event (connect) gibt?)

    Ich sehe auch gar kein Problem darin das es so gehandhabt wird. Es ist schließlich
    nicht vorgegeben in welcher Reihenfolge NetworkServerEvent() mehrere anstehende Events zurückgibt.
    (Es darf natürlich kein disconnect vor dem connect kommen, aber das kann es auch nicht.)
  • "Disconnect" in umgekehrter Reihenfolge:
    Disconnect Events werden nicht nach ihrem "Alter" verarbeitet.
    Der Disconnect-Event ist wie oben schon gesagt ein Event des indiviuellen Clients.
    Wenn also NetworkServerEvent() aufgerufen wird, dann kann man für jeden der
    Clients testen ob der noch verbunden ist, aber wenn nun mehrere gefunden
    werden kann man nicht sagen welcher früher die Verbindung getrennt hat.
    Es wird einfach der nächste Client der nicht mehr verbunden ist als nächsten
    Event zurückgeliefert.
    Das das jetzt genau die umgekehrte Reihenfolge des Verbindens ist liegt schon
    an unserer Implementierung, aber ist doch letztlich auch total egal.

    Wenn also mehrere disconnects gleichzeitig (also seit dem letzten NetworkServerEvent())
    anstehen ist die Reihenfolge durch den algorithmus, nicht durch das "Alter"
    bestimmt. Ob das nun vorwärts, rückwärts oder sonstwas ist spielt für die Anwendung keine
    Rolle, weil man ja sowiso aufgrund dieser Reihenfolge keine sinnvollen Entscheidungen treffen kann.

    Im Endeffekt sollte man was die Reihenfolge der Events bei verschiedenen Clients
    angeht keine Annahmen machen. Nur für jeden Client einzeln kann man sagen,
    das da die Reihenfolge garantiert wird: zuerst Connect, dann die Daten in
    der Reihenfolge wie sie gesendet worden sind (nicht aber zwingendermaßen in genau diesen
    Blöcken zusammengefasst), und am Ende das Disconnect.
  • SendNetworkData() zeigt Erfolg an:
    Der Rückgabewert besagt nur das erfolgreich "Abgeschickt" wurde. Er garantiert nicht
    das der Client auch alles bereits empfangen hat. Wenn SendNetworkData()
    immer auf eine Antwort des Zielrechners warten müsste bevor der Befehl
    zurückkehrt würde die Netzwerkkommunikation ein Program total
    lahmlegen.

    Der Rückgabewert von SendNetworkData() ist also nur begrenzt hilfreicht.
    Wenn du eine definitive Bestätigung für den Empfang brauchst, musst du dir die
    vom Server/Client explizit schicken lassen.

    Das könnte in der Hilfe vielleicht noch etwas deutlicher gemacht werden, aber ein
    Bug ist das hier definitiv nicht.
Christi hat geschrieben:scheiß buggy purebasic ! is doch echt zum kotzen auf nichts kann man sich verlassen ! und ja ich bin grad schlecht gelaunt und ja ihr
könnt euch nen dummen spruch sparn !
In der Regel schreien die die selber nichts können immer am lautesten wenn es um (angebliche oder echte)
Fehler geht die sie ausnahmsweise mal nicht selber verursacht haben.
Ich würde dir Fahrrad fahren empfehlen. Vielleicht hast du da ja mehr Erfolg.
Christi
Beiträge: 154
Registriert: 31.08.2004 14:17
Kontaktdaten:

Beitrag von Christi »

freak hat geschrieben:In der Regel schreien die die selber nichts können immer am lautesten wenn es um (angebliche oder echte)
Fehler geht die sie ausnahmsweise mal nicht selber verursacht haben.
Ich würde dir Fahrrad fahren empfehlen. Vielleicht hast du da ja mehr Erfolg.
Ich denk von mir selber, dass ich nicht die Regel bin.
Sry wegen meinem leichten Austicker. Man hätte es wohl anders oder garnicht formulieren können. Die Frage is auch inwiefern man überhaupt auf sowas (wie meinen Post) eingeht...
Und thx für die genauere Erklärung der Netzwerkbefehle, wäre in der Hilfe echt angebracht.

schönen Abend noch
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

@Freak
Vielen Dank erstmal für deine ausführliche Antwort, sie hilft mir schon sehr beim Verständnis, trotzdem ist noch nicht alles geklärt. Unter anderm hast du meinen einen Beitrag wohl nicht gelesen.
Also dann:

Es ist natürlich super, denn es ist einfach, das der PB-Server die Events (vor allem die der Clienten) automatisch abfragt und einem dann Arbeit abgenommen wird. Aber wenn der Server nichts weiter macht, als man auf der Clientseite eh selber machen muß, also in einer Schleife abfragt ob ein Clientevent eingegangen ist, dann wäre es besser wenn man das selst übernehmen könnte. Denn es ist sehr wohl wichtig, schnell mitzubekommen, ob ein Client disconnectet wurde. Würde man das selber machen können, so wäre das in unterschiedlichen Threads möglich und es käme nicht zu den Problemen. Läuft es so wie jetzt, dann kann man einfach keine Programme schreiben die extreme Serverlast aushalten müssen (viele Connect, Disconnects). Denn wenn es so wie in dem Test abläuft (das ist bei meinem geplanten Programm mehr als realistisch) so würden ständig "Geisterverbindungen" bestehen die Ständig überwacht werden und an die auch ständig noch Daten gesendet werden obwohl sie nicht da sind.
Das ist defintiv nicht Vorteilhaft für einige anwendungen und sollte irgendwie geändert werden, oder die Möglichkeit bestehen, nach dem Connect diese "Clientverbindungen" selbst abzufragen, damit es nicht zu diesen Problemen kommt.
Aber da ich schon gesehen hatte (kurz bevor du geantwortet hast), das die ClientID auch erst dann wieder freigegeben werden, wenn das Disconnect übergeben wurde, also keine Überschneidungen auftreten, ist dies nur ein "Ärgernis der besonderen Art" für mich, aber wenigstens kann man damit vorläufig leben.

Nun aber zu dem, was nicht richtig sein kann und du übersehen hast.

SendNetworkData(), ist TCP nicht genau dazu da, zu überprüfen ob Daten auch korrekt übertragen wurden!!? Also das verstehe ich jetzt nicht. Aber auch hier stimmt was nicht. Denn wie ich hier schon schrieb kann das mit dem Rückgabewert nicht stimmen, wie kann SendNetworkData() denn bitte sagen, das die Daten korrekt versand wurden, wenn der Client teilweise schon für über einer Minute die Verbindung beendet hat? Man kann doch nicht sagen, das Daten an einen Clienten abgesendet wurden, der gar nicht mehr existiert, das geht soweit ich weiß bei TCP doch nicht. Und das sieht man indem man gleichzeitig (na ja, direkt nacheinander) SendNetworkData() und SendNetworkString() nutzt, denn SendNetworkString() gibt im Gegensatz zu SendNetworkData() eine Fehlermeldung aus. SNString() gibt dann zurück, das beim Senden der Daten ein Fehler auftrag, klar, der Client existiert teilweise seit Minuten nicht mehr. Also wie bitte kann erstens SendNetworkData() sagen das DAten korrekt abgesendet wurden, obwohl bereits beim übergeben des CONNECTevents der Client bereits wieder getrennt war und ZWEITENS wie ist es zu erklären das beide FUnktionen unterschiedliches ausgeben, das ist doch Quatsch aus meiner Sicht, bzw. ein Bug. Nur da alles nicht so "Ideal" ist, weiß ich natürlich nicht wo der Fehler liegt.

Also der Rückgabewert von SendNetworkData() ist aus meiner Sicht fehlerhaft und zwar hast du recht, das es natürlich einfacher ist, das man erstmal die direkt abfragbaren Serverevents ausgibt, als ständig ne Schleife zu durchlaufen ist schon klar, den es ist ressourcenschonend, ähnlich hätte ich es selbst auch gemacht, aber man darf dies nicht ohne eine Sicherheitsroutine machen. Es kann nicht sein, das theoretisch (und sogar problemlos in der praxis möglich) einige Disconnecs minuten oder stundenlang nicht angezeigt werden. Eine Idee von mir dazu wäre erstmal intern was "fest" einzufügen, was man vielleicht später durch eine Zusatzfunktion vom User beinflussen kann:
Einfach dafür sorgen, das mindestens alle X Sekunden (sagen wir mal anfang 5) die "Clientschleife" durchlaufen wird, selbst wenn Serverevents anliegen. So bekommt man wenigstens innerhalb einer festgelegten Zeit das Disconnect mit. Das dürfte sich wohl auch recht einfach intern regeln lassen.

Gruß und schon mal danke für deine immer sehr klaren Worte :-)

Toshy
[edit]
hmm. ich habe weiter getestet und ich habe mich wohl etwas geirrt, aber das macht das Verhalten von PB nicht besser, nur auf eine andere Art unverständlich. Freak kann da aber wohl weiterhelfen.
Also der Unterschied zwischen SendNetworkString() und SendNetworkData() besteht wohl doch nicht, sondern es hangt nur davon ab, was zuerst verwendet wird. Man kann das einfach testen indem man die "Sendefunktionen" in der Reihenfolge austauscht bzw. auskommentiert:

Code: Alles auswählen

Select SEvent
        Case 1
          ;MessageRequester("PureBasic - Server", "A new client has connected !", 0)
          Debug "neuer Client: "+Str(ClientID)
          string.s = "0123456789" + Space(1000*10000)
          ;Debug "SendNetworkString1: " + Str( SendNetworkString(ClientID, "fdsdfrwer") )
          Debug "SendNetworkData1: " + Str( SendNetworkData(ClientID, @string, 10+1000*10000) )
          Debug "SendNetworkData2: " + Str( SendNetworkData(ClientID, @string, 10+1000*10000) )
          Debug "SendNetworkString2: " + Str( SendNetworkString(ClientID, "fdsdfrwer") )
Immer noch besteht das Problem, das die Daten angeblich korrekt (ab-)gesendet wurden sein sollen, obwohl das unmöglich ist, denn die Verbindung besteht schon längst nicht mehr. Also "bemerkt" die Sendefunktion nicht, das die Verbindung schon beendet ist ODER es wird bemerkt, nur die Errormeldung nicht weitergeleitet!? Was eigenartig ist, sendet man direkt nach diesem "fehlerhaften korrekten Senden" ;-) nochmals was, dann wird korrekt zurückgegeben, das nichts gesendet wurde. Also irgendwas kann da nicht so ganz stimmen. Vielleicht hilft Freak dies etwas weiter.
1. Win10
PB6.1
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Beitrag von freak »

Eventreihenfolge:
Ich verstehe dein Argument. Durch Abarbeiten gleichzeitiger Events mit einer Queue
(statt immer in gleicher Reihenfolge wie jetzt) sollte man dem eigentlich Herr werden können.
Ich werde mal sehen ob sich das machen lässt.

SendNetworkData() ist ein direkter wrapper zur send() winsock funktion: http://msdn2.microsoft.com/en-us/library/ms740149.aspx

Dort heißt es unter anderem: "The successful completion of a send does not indicate that the data was successfully delivered."

Also ich bin selber eigentlich kein wirklicher Experte was Netzwerk angeht, aber ich verstehe das so das TCP die korrekte Reihenfolge der Pakete garantiert,
und bei fehlenden Paketen eine Neusendung veranlasst, aber ich denke eben nicht das es damit 100% Erfolg garantieren kann.

Übrigens besteht die Verbindung vom Client zu Server bereits bevor das PB Program
den Event verarbeitet hat. (füge mal ein debug bei dem client code ein, jedesmal
wenn OpenNetworkConnection() was zurückgiebt, dann siehst du das.)
Das ist denke ich auch der Grund warum man wenig daten bereits senden kann
bzw warum das erste send klappt und das 2. nicht. Für die daten des ersten sends
ist eben noch Platz im TCP Puffer des Servers, aber für das 2. nicht. Da muss das
Serverprogramm die daten erst aus dem Puffer lesen damit man weiter senden kann.

Das ist wohl auch mit ein Grund warum erfolgreiches Senden nicht garantieren kann
das auch alles erfolgreich empfangen wurde. Es kann ja sein das alles korrekt im TCP Puffer
des Servers ankommt, aber das heißt ja noch lange nicht das das Serverprogram das auch ausliest.

So, ich hoffe das klärt die Sache jetzt... sonst bin ich nämlich auch mit meiner Weißheit am Ende :wink:
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Also soweit ich weiß, ist das nicht ganz so. Aber unabhängig davon, am Empfangsbuffer kann es nicht liegen, denn es ist egal ob das erste senden 10MB Daten beinhaltet oder nur ein Byte und bei den weiteren ist es auch egal.
Mir ist auch bekannt, das die Client-Serververbindung besteht, bevor das Event durch PB weitergeleitet wird, in dieser Zeit werden weitere Events bzw. DAten ja in den Empfangsbuffer geschrieben, was ich aber meine ist folgendes:
Server wird erstellt,Client erstellt nun Verbindung und beendet diese SOFORT wieder (innerhalb von Millisekunden), dies geschieht nun dutzende Male. Auf Der Serverseite werden die eingehenden Verbindungen nun langsamer verarbeiter als sie eingehen (z.B. weil Server ausgelaster). In diesem Falle rede ich mal zum Beispiel von der 20 Clientverbindung , diese wurde innerhalt der ersten 1-2 Sekunden der Serverlaufzeit erstellt und wieder beendet. Die Verbindung besteht also defakto NICHT mehr (habe es auch mit 2 getrennten PRogrammen getestet und das Clientprogramm dazu total beendet). Nun verarbeitet der Server nach und nach die Events und nach 20 Sekunden kommt er zu dem Connectevent des Clienten der schon seit 20 Sekunden beendet ist (Clientprogramm war sogar schon beendet), nun versucht der Server an diesen Clienten, dessen Verbindung gar nicht mehr besteht was zu senden und egal ob es ein Byte oder 10 MB sind, PB sagt, das es klappt. Da gar kein Empfangbuffer mehr bestehen kann, ist dies nicht korrekt.

Code: Alles auswählen

Debug "SendNetworkData0: " + Str( SendNetworkData(ClientID, @string, 1) )
          Debug "SendNetworkData1: " + Str( SendNetworkData(ClientID, @string, 1) )
sendet z.B. auch nur 2 Bytes, der Buffer kann also nicht voller sein, als wenn man beim ersten mal 10 MB sendet, aber das erste Senden klappt, das zweit nicht. Irgendwie verstehe ich das nicht. Da kann doch was nicht ganz stimmen.

[edit]
da du nun ja gesagt hast, das es nur eine Wrapperfunktion auf send ist, hilft das natürlich, denn dann kann es natürlich sehr gut sein, das es NICHT an PB liegt. Aber wenn dies nun auch bei SEND passiert, kann mir dann mal jemand der sich damit auskennt sagen, wie es zu diesem Verhalten kommen kann?
Zuletzt geändert von Toshy am 09.01.2007 21:00, insgesamt 1-mal geändert.
1. Win10
PB6.1
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Beitrag von freak »

Wie gesagt, für TCP Verbindungen besteht SendNetworkData() wirklich nur aus "return send(...);",
es wird also kaum ein Fehler auf der PB Seite sein.
Gesperrt