ich hab vor ein Remote-Desktop Programm zu schreiben, womit ich meine Windows Server fernsteuern kann.
Jetzt hab ich erstmal angefangen mit dem Programmieren des Netzwerkes,
hab damit aber große Probleme:
- Pakete gehen verloren
- Pakete kommen scheinbar doppelt an
- Pakete kommen in falscher Reihenfolge an
- Mit Debugger geht der Code gar nicht oder besser gesagt, eher "zufällig" und der gibt total komische Fehlermeldungen an.
So also irgendwie geht da gar nichts. Vom System her habe ich das so Programmiert:
- Server wird gestartet
- Dieser startet 2 Threads
- 1. Thread: Schleife, die Ereignisse im Netzwerk überprüft und auswertet. Wenn z.B. ein Paket eintrifft, so fügt dieser Thread den Inhalt des Paketes in eine Liste hinzu.
- 2. Thread: Dieser Bearbeitet die Liste und löscht bearbeitete Pakete bzw. die Elemente der Liste
Wenn der Client lokal auf den Server connected (127.0.0.1 ) gehts noch halbwegs, aber wenn es wirklich übers Netzwerk läuft, dann kommt jedes 2 Paket nicht an.
Servercode:
Code: Alles auswählen
OpenConsole()
; OnErrorSupport
Procedure error()
Select MessageRequester("Warning","Ein Fehler ist in der Zeile "+Str(GetErrorLineNR())+" aufgetreten",#MB_ICONWARNING | #MB_ABORTRETRYIGNORE)
Case 3
End
Case 4
error()
EndSelect
EndProcedure
OnErrorGosub(@error())
; Initialisieren
Declare NetworkHandle()
Declare ServerHandle()
#buffersize = 1000
Global quit.b
InitNetwork()
; Einfacher Messagehandler
Procedure Info(text.s,typ.b)
Select typ.b
Case 0
;Debug "Error: "+text
PrintN("Error: "+text)
;MessageRequester("Error",text.s,#MB_ICONSTOP)
Case 1
;Debug "Log: "+text
PrintN("Log: "+text)
;MessageRequester("Info",text.s,#MB_ICONINFORMATION)
Case 2
;Debug "Nachricht: "+text
PrintN("Nachricht:"+text)
;MessageRequester("Nachricht",text.s,#MB_ICONINFORMATION)
EndSelect
EndProcedure
; Startet Server
Procedure RunServer()
If CreateNetworkServer(2000)
Structure computer
id.l
EndStructure
Structure work ; Struktur für die Liste für das Abarbeiten der Pakete
id.l
*buffer
doit.b
EndStructure
Global client.computer
NewList ToDo.work()
CreateThread(@ServerHandle(),0)
CreateThread(@NetworkHandle(),0)
ProcedureReturn #True
EndIf
EndProcedure
Procedure ServerHandle() ; Procedure für das Empfangen von Paketen (Thread)
Repeat
Select NetworkServerEvent()
Case 1
Client\id = NetworkClientID()
Case 2 ; Wenn ein Paket empfangen wird
AddElement(Todo()) ; Eine Element wird in die Liste zu Abarbeitung hinzugefügt
todo()\id = NetworkClientID()
todo()\buffer = AllocateMemory(#buffersize) ; Speicher für das Paket wird reserviert
ReceiveNetworkData(todo()\id ,Todo()\buffer,#buffersize)
Todo()\doit = 1 ; Paket wird für die Bearbeitung freigegeben.
Case 4
Client\id = 0
Default
Delay(1)
EndSelect
Until quit
EndProcedure
Procedure NetworkHandle() ; Procedure für das Bearbeiten der Pakete (Thread)
Repeat
If CountList(Todo()) ; Wenn ein Paket für die Bearbeitung da ist
FirstElement(Todo()) ; Wird das erste Paket ausgewählt
If Todo()\doit ; Falls dieses Element für die Bearbeitung freigegeben ist
Select PeekB(todo()\buffer) ; Lese den ersten Byte aus ( hier sollte der immer 1 sein...später soll das sozusagen ein Befehl sein. z.B. ist 1 eine Nachricht und 2 Koordinaten und 3...)
Case 1 ; Falls 1 => Nachricht
info(PeekS(todo()\buffer+1),2) ; Liest die Nachricht und bringt sie auf den Bildschirm
EndSelect
FreeMemory(Todo()\buffer) ; Fertig bearbeitet => Speicher wieder freigeben
DeleteElement(Todo()) ; Element löschen
ResetList(Todo()) ; Liste reseten
EndIf
Else
Delay(1)
EndIf
Until quit
EndProcedure
;Hauptroutine
If RunServer()
info("Server wurde gestartet",1)
While quit = 0
Delay(10)
Wend
info("Server wurde gestoppt",1)
Else
Info("Server konnte nicht gestartet werden",0)
EndIf
End
Code: Alles auswählen
OpenConsole()
InitNetwork()
*buffer = AllocateMemory(100)
PokeB(*buffer,1) ; Schreibt den ersten Byte, der für den Befehl steht ( hier ist dieser 1 und bedeutet, das es sich um eine Nachricht handelt )
sid.l = OpenNetworkConnection("127.0.0.1",2000)
If sid
For x = 0 To 100
PokeS(*buffer+1,Space(50)) ; Leert den Text für die Nachricht
PokeS(*buffer+1,Str(x)) ; Schreibt den Text
PrintN(PeekS(*buffer+1)) ; Schreibt den Text, der gesendet wird in die Konsole
SendNetworkData(sid,*buffer,50) ; Verschickt das Paket ( 1+$Text )
Delay(1)
Next
CloseNetworkConnection(sid)
Else
PrintN("Konnte Server nicht finden")
EndIf
PrintN("Finish")
Input()
; IDE Options = PureBasic v3.94 (Windows - x86)
; CursorPosition = 11
; Folding = -
; DisableDebugger
Danke im Vorraus.
mfg. Kooky