TestClient - ReceiveNetworkData()

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

TestClient - ReceiveNetworkData()

Beitrag von uweb »

Ich habe offensichtlich schon zu lange nichts mehr in PureBasic gemacht.
Es ist definitiv nicht wie Radfahren. Man kann es wieder verlernen !
Nein, bitte kein Mitleid. Altersdemenz hat auch Vorteile :
Ich lerne täglich neue Leute kennen und werde mich unvorbelastet in Version 4.0 einarbeiten.

Jetzt aber ernsthaft. Ich habe mir Teile aus dem Forum und der Hilfe zu einem TestClient zusammengebastelt.
Er läuft zwar. Ist aber an zwei Stellen, die ich markiert habe, noch unschön :

1. Bei großen Antworten wird nur ein Teil empfangen
- edit :
- Eine Antwort sehe ich nur, wenn ich meinen lokalen Webserver anspreche.
- Im Web kommt zwar keine Fehlermeldung, aber die Antwort ist leer.

2. Das Kopieren der Antwort in die Zwischenablage führt manchmal zu "Invalid memory access".
- edit : ERLEDIGT
- Das Problem lag wohl nicht an GetGadgetText(), sondern an den API-Aufrufen.
- Keine Ahnung weshalb ich nicht gleich die PureBasic-Funktion benutzt habe.
- So gehts :

Code: Alles auswählen

    If EventGadgetID()=7
      Inhalt$=GetGadgetText(6)
      SetClipboardText(Inhalt$)
    EndIf

Ich bin für jeden Tipp dankbar !!!

Code: Alles auswählen

OpenWindow(0, 0, 0, 300, 400, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "TestClient")

If CreateMenu(0, WindowID())
  MenuTitle("Info")
    MenuItem(1, "About")
EndIf

CreateGadgetList(WindowID())
IPAddressGadget(0, 5, 5, 145, 20)
StringGadget(1, 215, 5, 20, 20, "80")
ButtonGadget(2, 25, 30, 100, 20, "Verbinden")
ButtonGadget(3, 175, 30, 100, 20, "Senden")
EditorGadget(4, 5, 55, 290, 290, "")

TextGadget(5, 5, 350, 290, 45, "Bitte IP oder Port ggf. ändern und "+Chr(34)+"Verbinden"+Chr(34)+" drücken.",#PB_Text_Border )

EditorGadget(6, 5, 55, 290, 290, "")
ButtonGadget(7, 175, 30, 100, 20, "Kopieren")

HideGadget(6, 1)
HideGadget(7, 1)

SetGadgetState(0,MakeIPAddress(127,0,0,1))
SetGadgetText(4,"GET /isapi.htm HTTP/1.1"+Chr(13)+Chr(10)+"Request Method: GET"+Chr(13)+Chr(10)+"Request URI: /isapi.htm"+Chr(13)+Chr(10)+"Request Version: HTTP/1.1"+Chr(13)+Chr(10)+"Host: 192.168.2.2"+Chr(13)+Chr(10)+"User-Agent: Mozilla/5.0 (Windows; U; Win98; de-DE; rv:1.5a) Gecko/20030728 Mozilla Firebird/0.6.1"+Chr(13)+Chr(10)+"Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1"+Chr(13)+Chr(10)+"Accept-Language: de-DE,de;q=0.8,en-us;q=0.5,en;q=0.3"+Chr(13)+Chr(10)+"Accept-Encoding: gzip,deflate"+Chr(13)+Chr(10)+"Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7"+Chr(13)+Chr(10)+"Keep-Alive: 300"+Chr(13)+Chr(10)+"Connection: keep-alive"+Chr(13)+Chr(10)+Chr(13)+Chr(10))
DisableGadget(3, 1)
DisableGadget(4, 1)
   
;#Puffergroesse = 10485576
;#Puffergroesse = 16384
#Puffergroesse = 32768
Puffer=AllocateMemory(#Puffergroesse)

  If InitNetwork()=0
    MessageRequester("Fehler", "Kein Netzwerk gefunden.", 0)
  EndIf

AddKeyboardShortcut(0, #PB_Shortcut_F1, 1)

DetachMenu() 

Repeat

  EventID=WaitWindowEvent()
  
  If EventID=#PB_Event_Menu
    If EventMenuID()=1
      MessageRequester("Info","TestClient von Uwe Beisler",0)
    EndIf
  EndIf
 
  If EventID=#PB_Event_Gadget
    If EventGadgetID()=2  ;Verbinden
      DisableGadget(3, 1)
      DisableGadget(4, 1)
      SetGadgetText(5,"Versuche Server zu erreichen.")
      Host$=GetGadgetText(0)
      Port$=GetGadgetText(1)
      ConnectionID.l = OpenNetworkConnection(Host$,Val(Port$))
      If ConnectionID = 0
        SetGadgetText(5,"Server ist nicht erreichbar."+Chr(13)+Chr(10)+"Bitte IP oder Port neu eingeben und "+Chr(34)+"Verbinden"+Chr(34)+" drücken.")
      Else
        SetGadgetText(5,"Server ist erreichbar."+Chr(13)+Chr(10)+"Bitte Anfrage ggf. ändern und "+Chr(34)+"Senden"+Chr(34)+" drücken.")
          HideGadget(6, 1)
          HideGadget(7, 1)
        DisableGadget(3, 0)
        DisableGadget(4, 0)
      EndIf
    EndIf

    If EventGadgetID()=3  ;Senden
      SetGadgetText(0,Host$)
      SetGadgetText(1,Port$)
      Anfrage$ = GetGadgetText(4)
      SendNetworkData(ConnectionID, @Anfrage$, Len(Anfrage$))
      Antwort$=""
;******* 1. Problem
      Repeat
        Delay(10)
        If NetworkClientEvent(ConnectionID)=2
          Laenge = ReceiveNetworkData(ConnectionID,Puffer,#Puffergroesse)
          Antwort$=Antwort$+PeekS(Puffer)
          ElseIf NetworkClientEvent(ConnectionID)=3
            ReceiveNetworkFile(ConnectionID,Antwort$)
            Laenge = 0
        EndIf
      Until Laenge<>#Puffergroesse
;*******
          SetGadgetText(6,Antwort$)
          HideGadget(6, 0)
          HideGadget(7, 0)
          DisableGadget(3, 1)
          DisableGadget(4, 1)
          SetGadgetText(5,"Antwort erhalten."+Chr(13)+Chr(10)+"Bitte Antwort ggf. ändern und "+Chr(34)+"Kopieren"+Chr(34)+" drücken, oder IP bzw. Port ggf. ändern und "+Chr(34)+"Verbinden"+Chr(34)+" drücken.")
      CloseNetworkConnection(ConnectionID)


    EndIf

    If EventGadgetID()=7
      ;CF_OEMTEXT
      ;CF_TEXT
      If OpenClipboard_(0)
        EmptyClipboard_()
;******* 2. Problem
        Inhalt$=GetGadgetText(6)
;*******
        SetClipboardData_(#CF_OEMTEXT,Inhalt$)
        CloseClipboard_()
      EndIf 
    EndIf

  EndIf

  If EventID = #PB_EventCloseWindow
    Exit=1
    FreeMemory(Puffer)
  EndIf
 
Until Exit=1
End
Zuletzt geändert von uweb am 07.02.2006 15:48, insgesamt 1-mal geändert.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: TestClient - ReceiveNetworkData()

Beitrag von AND51 »

uweb hat geschrieben:Nein, bitte kein Mitleid. Altersdemenz hat auch Vorteile :
Ich lerne täglich neue Leute kennen und werde mich unvorbelastet in Version 4.0 einarbeiten.
Hahaha! Ich krieg mich gar nicht mehr ein vor lachen... :lol: :lol: :lol: Naja, ist aber schön, dass du die Fehler gefunden hast!
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Beitrag von Batze »

Er hat doch noch gar keine komplette Lösung, oder? :?

Code: Alles auswählen

      If NetworkClientEvent(ConnectionID)=2
          Laenge = ReceiveNetworkData(ConnectionID,Puffer,#Puffergroesse)
          Antwort$=Antwort$+PeekS(Puffer)
          ElseIf NetworkClientEvent(ConnectionID)=3
            ReceiveNetworkFile(ConnectionID,Antwort$)
            Laenge = 0
        EndIf
      Until Laenge<>#Puffergroesse
Ich glaube da liegt ein Fehler, denn du fragst NetworkClientEvent() zwei mal ab. Musst du aber nur einmal und dann in eine Variable speichern.
Oder du benutzt Select.

Damit ist aber wahrscheinlich dein Problem noch nicht gelöst.
Zuletzt geändert von Batze am 07.02.2006 15:20, insgesamt 3-mal geändert.
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Oh, stimmt, sry. Nur zu 2.) hat er eine Lösung gefunden. Sry nochmal!
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Beitrag von uweb »

Damit ist aber wahrscheinlich dein Problem noch nicht gelöst.
Richtig! Danke trotzdem!

Code: Alles auswählen

      Repeat
        Delay(10)
        NCE = NetworkClientEvent(ConnectionID)
        If NCE=2
          Laenge = ReceiveNetworkData(ConnectionID,Puffer,#Puffergroesse)
          Antwort$=Antwort$+PeekS(Puffer)
          ElseIf NCE=3
            ReceiveNetworkFile(ConnectionID,Antwort$)
            Laenge = 0
        EndIf
      Until Laenge<>#Puffergroesse
Hat nichts gebracht. Ich empfange nach wie vor nur einen Teil von großen Antworte. Das läßt sich mit

Code: Alles auswählen

#Puffergroesse = 1024
gut nachvollziehen.
Und, im Internet bekomme ich leere Antworten.

Wie verhält es sich den bei euch ? Vielleicht liegt der Fehler ja ganz wo anderst.
emptee
Beiträge: 10
Registriert: 13.09.2004 11:44
Wohnort: Dortmund
Kontaktdaten:

Beitrag von emptee »

Nein, das Problem liegt nicht woanders.

Selbst die Puffergroesse von 1024 ist noch zu gross, um sicher zu sein, immer einen vollen Buffer (d.h. 1024 Zeichen) geliefert zu bekommen;
alternativ ist das Delay zu klein.

Bei einem Delay von 10 ms sind das immerhin fast 1 MBit/s, die Du da als Datenstrom voraussetzt (ohne jetzt sonstige Programmlaufzeiten zu berücksichtigen).

Denn 1024 * 100 sind 100 kByte/s also 800kbit/s. Nutzdaten wohlgemerkt, der ganze Protokolloverhead fehlt da noch.

Mit was für einer Bandbreite testest Du das Programm denn?

ciao, Mario
http://www.surfkraft.de - instrumental surf weblog
emptee
Beiträge: 10
Registriert: 13.09.2004 11:44
Wohnort: Dortmund
Kontaktdaten:

Beitrag von emptee »

Ach so, mein Fazit habe ich noch vergessen:

Konsequenz sollte also sein, nicht das Delay raufzusetzen oder die Puffergroesse, sondern sich Gedanken über ein sinnvolles Protokoll
zu machen, welches man für die Kommunikation benutzt.

NNTP z.B. liefert zum Schluss als letzte Zeile immer einen Punkt gefolgt von CR/LF. Das kann man abfragen und ist dann sicher, daß man die komplette Serverausgabe auch erhalten hat.

ciao, Mario
http://www.surfkraft.de - instrumental surf weblog
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Beitrag von Batze »

uweb hat geschrieben: Hat nichts gebracht.
Ich denke doch, dass es was gebracht hat, nämlich, dass du jetzt auch Dateien empfangen kannst (wenn es denn mal geht :freak: ).
Vorher wurden die Events außer 2="Daten Empfangen" ignoriert.

Vermute ich richtig, dass das letzte Empfangene Byte immer 0 ist?
Dann könntest du so überprüfen, ob die Daten komplett da sind.
Das wäre dann so ähnlich wie es emptee empfohlen hat.
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Beitrag von uweb »

Danke für den Tipp !

Das mit der Bandbreite kann gut sein. Mit lokalen Webserver habe ich den Server auf dem gleichen PC gemeint. Also Bandbreite fett. Im Internet bin ich über DSL mit 2 Mbit. Da ich z.Zt. nur über Proxy ins Forum komme habe ich hier wesentlich weniger. Deshalb habe ich meinen Test auch mit google gemacht.

Das mit dem Protokoll will ich eher nicht umsetzen. Der TestClient soll ja ein Hilfswerkzeug beim Entwickeln von Anwendungen sein. Bei den Anwendungen an sich macht das sicher Sinn wenn man die Freiheit hat.
Mein Focus liegt z.Zt. auf HTTP mit eventueller Erweiterung (WebDAV).
Nein, das Problem liegt nicht woanders.
Bedeuted das Du hast es getestet und kommst zu anderen Ergebnissen ?

Wenn nicht reicht reicht irgendein 0815-Webserver oder eine die IP eines Servers im Internet. Die Anfrage muß nicht editiert werden. Eine Fehlermeldungsseite ist ja auch eine Seite.

Daß die Antwort nicht komplett ist erkenne ich daran, daß sie mitten im HTML-Dokument endet.

edit :
Ich wollte gerade das mit dem Null-Byte testen. Aber es ist schon fast ein viertel Jahrhundert her, daß ich Peek und Poke benutzt habe.

Code: Alles auswählen

#Puffergroesse = 1024
Puffer=AllocateMemory(#Puffergroesse)
For i = 0 To #Puffergroesse - 1
  PokeB(@Puffer+i, 42)
Next
...
        If NCE=2
          Laenge = ReceiveNetworkData(ConnectionID,Puffer,#Puffergroesse)
          Antwort$=Antwort$+PeekS(Puffer)
          If PeekB(@Puffer + Len(Antwort$) + 1 ) = 0
            MessageRequester("Info","Puffer enthält den Bytwert 0",0)
          EndIf
          ElseIf NCE=3
            ReceiveNetworkFile(ConnectionID,Antwort$)
            Laenge = 0
        EndIf
Bringt "Invalid memory access" und hält bei EventID=WaitWindowEvent().
Zuletzt geändert von uweb am 07.02.2006 16:41, insgesamt 2-mal geändert.
emptee
Beiträge: 10
Registriert: 13.09.2004 11:44
Wohnort: Dortmund
Kontaktdaten:

Beitrag von emptee »

Ich brauch' das nicht testen, das zugrunde liegende Problem ist offensichtlich.

Du wirst mit Deinem zitierten Code unter verschiedenen Netzwerkbedingungen NIE vernünftige Ergebnisse erzielen.

Es REICHT NICHT, zu prüfen, ob der Buffer ganz voll oder leer ist, es gibt bei Dir 1023 Zwischenzustände, die ALLE zum Abbruch der Aktivitäten führen, weil irrtümlicherweise angenommen wird, daß die Verbindung beendet ist.

Du musst ZWINGEND andere Anhaltspunkte finden, die signalisieren, daß Du alle Daten erhalten hast. Das nimmt Dir PureBasic nicht ab.

ciao, Mario
http://www.surfkraft.de - instrumental surf weblog
Antworten