Da hier das erste mal mit Netzwerk gearbeitet wird, ein paar grundlegende infos und regeln.
ReceiveNetworkData holt alles was sich im Empfangsbuffer in der Zwischenzeit an Daten aufgelaufen ist.
SendNetworkData übergibt die die Daten an den Sendebuffer. Der Rückgabewert gibt nur an, das die Daten an den Sendebuffer übergeben wurde und nicht das die Daten gesendet wurde.
Die Daten werden als Paket über das Netzwerk übertragen. Daten werden je nach PDU größe in mehreren Pakete versendet.
Bei TCP wird nur gewährleistet das die Daten bis 64kB konsistent in der richtigen Reihenfolge übertragen werden.
Nicht das die Daten erfolgreich Komplet gesendet oder empfangen wurde.
Somit kann es sein das bei Aufruf von ReceiveNetworkData bereits ein Teil der Daten aus dem Empfangsbuffer gelesen werden kann, obwohl noch nicht alle Pakete empfangen wurde.
Das die Daten vollständig gesendet oder empfangen wurde, ist die Aufgabe des Programmierers.
Um nicht das Programm zu blockieren, ist es immer zu empfehlen, die Kommunikation in einem Thread auszulagern.
Hier mal ein Grundsätzlicher Aufbau für einen Client der Textdaten empfängt.
Das Trennzeichen haben ich hier mal das Return (#CR$ - Zeichen 13) genommen.
Ist aber noch nicht alles drin. Zum Beispiel wenn der Server Ausfällt oder das die Netzwerkverbindung gestört ist, kann es sein das der Client diese nicht merk.
Somit sollte noch ein Timeout programmiert, wenn vom Server keine Daten mehr kommen und eine Reconnect versucht werden.
Den code habe ich aber nicht nicht Komplet getestet.
Code: Alles auswählen
;-TOP
CompilerIf Not #PB_Compiler_Thread
CompilerError "Use Compiler Option ThreadSafe!"
CompilerEndIf
If Not InitNetwork()
MessageRequester("Error", "Faild init Network!")
End
EndIf
Structure udtClientData
; Thread
ThreadID.i
Exit.i
; Connection
Hostname.s
Port.i
ConnectionID.i
; Data
*Buffer
Empfang.s
EndStructure
Procedure thNetworkClient(*data.udtClientData)
Protected receive_len, pos, text.s
With *data
Debug "Init Thread Resources"
\Buffer = AllocateMemory(8192)
Debug "Init Network Connection"
; Einsprungpunkt Verbindung wieder herstellen
Reconnect:
Repeat
If \Exit
Break
EndIf
\ConnectionID = OpenNetworkConnection(\Hostname, \Port, #PB_Network_TCP)
If Not \ConnectionID
; 5 Sekunden warten bis zum nächsten versuch
Delay(5000)
EndIf
Until \ConnectionID
If \ConnectionID
Debug "Network Connection ok"
EndIf
Repeat
If \Exit
Break
EndIf
Select NetworkClientEvent(\ConnectionID)
Case #PB_NetworkEvent_Data
; Daten zum abholen im Buffer
receive_len = ReceiveNetworkData(\ConnectionID, \Buffer, 8192)
; Daten als String auslesen und zum String hizufügen
\Empfang + PeekS(\Buffer, receive_len, #PB_Ascii)
; String auf Endezeichen prüfen. Kann auch mehrere enthalten
Repeat
pos = FindString(\Empfang, #CR$) ; Endezeichen Chr(13)
If pos
; Daten übernehmen bis Endezeichen
text = Left(\Empfang, pos - 1)
; Empfangs String korrigieren
\Empfang = Mid(\Empfang, pos + 1) ;
;TODO -> Hier den Part abarbeiten
Debug text
; <-
EndIf
Until pos = 0
Case #PB_NetworkEvent_Disconnect
; Server hat die Verbindung getrennt
CloseNetworkConnection(\ConnectionID)
\ConnectionID = 0
Break
Case #PB_NetworkEvent_None
; Nicht zu tun. Kleine Pause (CPU schonen)
Delay(10)
EndSelect
ForEver
If Not \Exit
Goto Reconnect
EndIf
; Verbindung abbauen
If \ConnectionID
CloseNetworkConnection(\ConnectionID)
\ConnectionID = 0
EndIf
Debug "Release Thread Resources"
FreeMemory(\Buffer)
\ThreadID = 0
\Exit = 0
EndWith
EndProcedure
;- Main
Global ClientData.udtClientData
ClientData\Hostname = "192.168.200.188"
ClientData\Port = 80
If OpenWindow(0, 50, 40, 300, 150, "Test Network Client", #PB_Window_SystemMenu)
ClientData\ThreadID = CreateThread(@thNetworkClient(), @ClientData)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
; Thread beenden
ClientData\Exit = #True
; Warten auf Thread
If WaitThread(ClientData\ThreadID, 10000) = 0
; Thread beenden fehlgeschlagen
KillThread(ClientData\ThreadID)
EndIf
EndIf