Seite 1 von 2
Gleicher Code, nur UDP
Verfasst: 25.02.2016 01:23
von Moxl
Guten Abend,
bin gerade dabei mich mit UDP auseinander zu setzen, also habe ich mal ein ganz einfaches Server/Client Programm gebastelt.
So, jetzt habe ich auch eine ganz einfache Frage
Wieso funktioniert dieses Model, ...
Server:
Code: Alles auswählen
Procedure server(param)
Repeat
event=NetworkServerEvent()
Select event
Case #PB_NetworkEvent_Connect
PrintN("Neuer Client verbunden. ID: "+Str(EventClient()))
Case #PB_NetworkEvent_Data
crude$=Space(2048)
received=ReceiveNetworkData(EventClient(), @crude$, 2048)
newcrude$=RTrim(crude$)
PrintN(Str(received)+" Bytes empfangen. ID: "+Str(EventClient())+" Data: "+newcrude$)
Case #PB_NetworkEvent_Disconnect
PrintN("Client getrennt. ID: "+Str(EventClient()))
Case #PB_NetworkEvent_None
Delay(10)
EndSelect
ForEver
EndProcedure
OpenConsole()
If InitNetwork()<>0
PrintN("Netzwerk initialisiert")
If CreateNetworkServer(0, 6600, #PB_Network_TCP)<>0
PrintN("Server gestartet")
PrintN("")
CreateThread(@server(), param)
Repeat
input$=Input()
Until input$="exit"
End
EndIf
EndIf
Client:
Code: Alles auswählen
Procedure client(verbindung)
Repeat
event=NetworkClientEvent(verbindung)
Select event
Case #PB_NetworkEvent_Data
PrintN("Daten empfangen. Data: ")
Case #PB_NetworkEvent_Disconnect
PrintN("Verbindung getrennt.")
Case #PB_NetworkEvent_None
Delay(10)
EndSelect
ForEver
EndProcedure
OpenConsole()
If InitNetwork()<>0
PrintN("Netzwerk initialisiert")
verbindung=OpenNetworkConnection("server666.no-ip.biz", 6600, #PB_Network_TCP)
If verbindung<>0
PrintN("Verbindung aufgebaut")
PrintN("")
CreateThread(@client(), verbindung)
Repeat
input$=Input()
If input$<>""
bytes=SendNetworkData(verbindung, @input$, Len(input$))
PrintN(Str(bytes)+"/"+Str(Len(input$))+" Bytes gesendet.")
EndIf
Until input$="exit"
End
EndIf
EndIf
wenn man aber einfach "TCP" durch "UDP" ändert, nicht mehr?
(Bitte bei beidem den Unicode Modus ausschalten!)
Der Server zeigt noch nichtmal an, ob ein Client connected ist.
Kann mir das jemand kurz erklären?
Danke schonmal im Vorraus

Re: Gleicher Code, nur UDP
Verfasst: 25.02.2016 17:19
von man-in-black
Hi,
habs jetzt nicht getestet (und bediene mich auch eher Halbwissen), aber du musst sowohl den Server als auch den
Client als UDP starten.
Dass du keinen "Beitritt des Clients" siehst, liegt an UDP selbst. Server und Client "sprechen" sich nicht wie bei TCP ab,
sondern senden einfach auf gut Glück Datenpakete, wenn dies gefordert ist. Guck mal bei "OpenNetworkConnection" in der Hilfe.
Dort steht, dass bei UDP nur intern ein Vermerk gemacht wird, also noch kein Kontakt zum Server selbst aufgenommen wird.
Folglich kann der Server gar nicht wissen, dass er Clienten hat.
MFG
MIB
P.S. Habs jetzt doch mal durchlaufen lassen. Sowohl TCP als auch UDP klappen ohne Probleme mit deinem Code. Einzig
das Erfassen der Clients vom Server wird nicht beachtet (s.o.).
Re: Gleicher Code, nur UDP
Verfasst: 25.02.2016 21:22
von Moxl
Ja soweit ist mir das alles klar wie udp funktioniert, und das der server nicht anzeigt das ein client connected kann ich ja dann auch noch verstehen wobei ich vor 1-2 Jährchen schonmal ein udp model gemacht habe und es dort funktioniert hat.
Was ich aber nicht verstehe ist, dass wenn man jetzt daten sendet, nichts ankommt. Auch wenn man 100 mal was sendet...
Hat das bei dir funktioniert?
Re: Gleicher Code, nur UDP
Verfasst: 26.02.2016 00:23
von man-in-black
P.S. Habs jetzt doch mal durchlaufen lassen. Sowohl TCP als auch UDP klappen ohne Probleme mit deinem Code.
Ich musste nur die Serveradresse auf den Localhost umschreiben, damit ichs überhaupt testen konnte.
server666.no-ip.biz
Wie hast du denn deinen Server aufgesetzt? Die Verbindung scheint ja nicht nur über deinen PC sondern übers Netz zu laufen?
Hohe Datenverlustrate bis zum Ziel? Mag ein Zwischenknoten deine Anfrage oder dich nicht?

(Sind nur spontane Ideen auf Basis von Halbwissen)
Re: Gleicher Code, nur UDP
Verfasst: 26.02.2016 11:47
von NicTheQuick
Falls du über einen Router gehst, musst du natürlich den Port für TCP und für UDP freischalten und nicht nur für eins von beiden.
Re: Gleicher Code, nur UDP
Verfasst: 26.02.2016 19:03
von Moxl
Ahh
es liegt wahrscheinlich an der portfreigabe... wie schon angenommen lass ich den server ja durch den router laufen,
wenn ich localhost eingebe funktioniert alles.
Jetzt stört mich nur noch das der Server nicht erkennt wenn ein Client connected.
Da muss ich mir wohl was überlegen wie der Server es checkt.
Danke für die Antworten
EDIT: Jop, musste UDP beim Router freigeben. Jetzt funktionierts

Danke

Re: Gleicher Code, nur UDP
Verfasst: 29.02.2016 10:01
von grapy
siehe auch:
https://de.wikipedia.org/wiki/User_Datagram_Protocol
UDP ist ein verbindungsloses, nicht-zuverlässiges und ungesichertes wie auch ungeschütztes Übertragungsprotokoll.
Das bedeutet, es gibt keine Garantie, dass ein einmal gesendetes Paket auch ankommt, dass Pakete in der gleichen Reihenfolge ankommen,
in der sie gesendet wurden, oder dass ein Paket nur einmal beim Empfänger eintrifft.
Daher gibt es auch keinen Connect vom Client. Dieser feuert nur Pakete ins Netzwerk. Die kommen eben an oder nicht.
Re: Gleicher Code, nur UDP
Verfasst: 16.03.2016 21:04
von Moxl
Hallo,
jetzt habe ich die Codes mal so umgeschrieben, dass ein Bild gesendet wird.
Allerdings habe ich jetzt wieder das selbe Problem wie am anfang... mit TCP klappt alles und mit UDP sendet er erst gar nichts
woran liegt das?
Server:
Code: Alles auswählen
UseJPEGImageEncoder()
UseJPEGImageDecoder()
If OpenWindow(0, 0, 0, 500, 500, "Bild")
ImageGadget(0, 0, 0, 500, 500, 0)
EndIf
OpenConsole("Server")
If InitNetwork()<>0
PrintN("Netzwerk initialisiert")
If CreateNetworkServer(0, 6600, #PB_Network_TCP)<>0
PrintN("Server gestartet")
PrintN("")
Repeat
Delay(10)
event=NetworkServerEvent()
Select event
Case #PB_NetworkEvent_Connect
clientid=EventClient()
Case #PB_NetworkEvent_Data
Debug "daten empfangsbereit"
clientid=EventClient()
size=0
sizereceived=ReceiveNetworkData(clientid, @size, 4)
If size=1
clientid=EventClient()
PrintN("Neuer Client verbunden. ID: "+Str(clientid))
Else
PrintN(Str(sizereceived)+" Bytes empfangen. ID: "+Str(clientid)+" Data: "+Str(size))
*daten=AllocateMemory(size)
errorcounter=0
ReceivedBytes=0
Repeat
result=ReceiveNetworkData(clientid, *daten+ReceivedBytes, size-ReceivedBytes)
If result=-1
Delay(1)
errorcounter+1
Else
ReceivedBytes+result
errorcounter=0
EndIf
Until ReceivedBytes=size Or errorcounter > 5000
PrintN(Str(ReceivedBytes)+" Bytes empfangen. ID: "+Str(clientid))
If ReceivedBytes=size
If CatchImage(0, *daten)
SetGadgetState(0, ImageID(0))
EndIf
FreeMemory(*daten)
EndIf
EndIf
Case #PB_NetworkEvent_Disconnect
clientid=EventClient()
PrintN("Client getrennt. ID: "+Str(clientid))
Case #PB_NetworkEvent_None
Delay(10)
EndSelect
event=WindowEvent()
Until event=#PB_Event_CloseWindow
End
EndIf
EndIf
Client:
Code: Alles auswählen
UseJPEGImageEncoder()
UseJPEGImageDecoder()
OpenConsole("Client")
If InitNetwork()<>0
PrintN("Netzwerk initialisiert")
verbindung=OpenNetworkConnection("localhost", 6600, #PB_Network_TCP)
If verbindung<>0
PrintN("Verbindung aufgebaut")
PrintN("")
hello=1
SendNetworkData(verbindung, @hello, 4)
Repeat
input$=Input()
If input$<>""
If LoadImage(0, "") ;<----- IRGEND EIN BILD EINFÜGEN
*bild=EncodeImage(0, #PB_ImagePlugin_JPEG)
*daten=AllocateMemory(4+MemorySize(*bild))
PokeL(*daten, MemorySize(*bild))
MoveMemory(*bild, *daten+4, MemorySize(*bild))
errorcounter=0
sendbytes=0
Repeat
result=SendNetworkData(verbindung, *daten+sendbytes, MemorySize(*daten)-sendbytes)
If result=-1 Or result=0
Delay(1)
errorcounter+1
Else
errorcounter=0
sendbytes+result
EndIf
Until sendbytes=MemorySize(*daten) Or errorcounter>5000
PrintN(Str(sendbytes)+"/"+Str(MemorySize(*daten))+" Bytes gesendet.")
FreeMemory(*bild)
FreeMemory(*daten)
FreeImage(0)
EndIf
EndIf
Until input$="exit"
End
EndIf
EndIf
(Beim Client müsst ihr den Pfad von dem Bild angeben.)
Hoffe Ihr könnt mir wiedermal helfen

Re: Gleicher Code, nur UDP
Verfasst: 16.03.2016 21:39
von HeX0R
Du kannst nicht so einfach ein Bild per UDP versenden.
UDP nimmt man dann, wenn man Dinge überträgt, bei denen es egal ist, ob Pakete mal verloren gehen, wie z.B. Video oder Audio Streams.
Wenn Deinem Bild aber ein Paket fehlt, oder die Reihenfolge falsch ist (beides bei UDP möglich), lässt sich das gar nicht mehr darstellen.
Da musst Du schon etwas mehr Gehirnschmalz einsetzen, z.b. die einzelnen Pakete markieren und dann beim Empfänger schauen, ob alle da sind und auch in der richtigen Reihenfolge.
Dann hast Du aber schon wieder einen Handshake, der den Vorteil von UDP nahezu zunichte macht.
Re: Gleicher Code, nur UDP
Verfasst: 16.03.2016 21:49
von STARGÅTE
Bei mir funktioniert dein Code nicht mal mit TCP.
"IRGEND EIN BILD EINFÜGEN" scheint nicht zu klappen.
Wie schon zuvor geschrieben wurde, sind das zwei völlig verschiedene Protokolle (mit unterschiedlichen Anwendungsgebieten).
Da du nun zwei mal SendNetworkData() in deinem Code hast:
Code: Alles auswählen
SendNetworkData(verbindung, @hello, 4)
SendNetworkData(verbindung, *daten+sendbytes, MemorySize(*daten)-sendbytes)
Unter UDP kann es nun sein, dass zuerst dein Bild ankommt und dann erst dein @hello
Lass dir doch mal ein bisschen mehr Debuggen, z.B. das resultat von SendNetworkData() oder ReceiveNetworkData()
Edit: Ah ich muss bei Input etwas reinschreiben.
Ich bekomme bei SendNetworkData() immer -1, vermutlich weil die Puffergröße die von UDP überschreitet
Anmerkungen
Bei UDP-Verbindungen beträgt die maximale 'Länge' 2048. Bei TCP-Verbindungen beträgt die maximale 'Länge' 65536.
Du musst dein Bild also vermutlich in "Häpchen" senden.