[B3D] {UDP} Schleppender Austausch
Übersicht

![]() |
N0XBetreff: [B3D] {UDP} Schleppender Austausch |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo, Community!
Ich habe folgendes Problem: Mein Spiel hat einen viel zu schleppenden Datenaustausch. Hier der Server-Code: [AUSKLAPPEN] Global timer=CreateTimer(40)
;--------------------------------------------------------------------------------------------| Type Player Field x#,y#,z# Field pitch,yaw,roll Field ip,port% Field aktiv End Type Type Gegner Field x#,y#,z# End Type Global svr = CreateUDPStream(7142) Global write_udp = CreateUDPStream(7143) Global send_milli#,read_milli#,readsvr,readav,rbyte,plycount,maxply While Not (KeyHit(1)) WaitTimer timer UDP() Wend CloseUDPStream(write_udp) CloseUDPStream(svr) End FreeEntity player Function UDP() readsvr = RecvUDPMsg(svr) If readsvr <> 0 Then readav = ReadAvail(svr) If readav <> 0 Then port = UDPMsgPort(svr) ip = UDPMsgIP(svr) rbyte = ReadByte(svr) Select rbyte Case 1 name$ = ReadString(svr) For p.Player = Each Player WriteByte svr,1 WriteInt svr,ip WriteInt svr,port SendUDPMsg svr,p\ip,p\port WriteByte svr,1 WriteInt svr,p\ip WriteInt svr,p\port WriteString svr,name$ SendUDPMsg svr,ip,port Next p.Player = New Player p\ip$ = ip p\port = port Print "Player Connected... "+name$ Case 2 For p.Player = Each Player If ip = p\ip And port = p\port Then Delete p End If Next For p.Player = Each Player WriteByte svr,2 WriteInt svr,ip WriteInt svr,port SendUDPMsg svr,p\ip,p\port Next Print "Player Disconnected..." Case 3 For p.Player = Each Player If p\port = port And p\ip = ip Then p\x = ReadFloat(svr) p\y = ReadFloat(svr) p\z = ReadFloat(svr) p\pitch = ReadInt(svr) p\yaw = ReadInt(svr) p\roll = ReadInt(svr) p\aktiv = ReadByte(svr) End If Next End Select End If End If read_milli = MilliSecs()+32 If send_milli < MilliSecs() Then For s.Player = Each Player For p.Player = Each Player If p\port <> s\port Then WriteByte svr,3 WriteInt svr,s\ip WriteInt svr,s\port WriteFloat svr,s\x WriteFloat svr,s\y WriteFloat svr,s\z WriteInt svr,s\pitch WriteInt svr,s\yaw WriteInt svr,s\roll WriteByte svr,s\aktiv SendUDPMsg svr,p\ip,p\port End If Next Next send_milli = MilliSecs()+32 End If End Function Function INT_IP(IP$) a1=Int(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a2=Int(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a3=Int(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a4=Int(IP$) Return (a1 Shl 24) + (a2 Shl 16) + (a3 Shl 8 ) +a4 End Function Und hier der Client-Code: [AUSKLAPPEN] Global listen_udp = CreateUDPStream()
Global svr = CreateUDPStream(Rnd(100,8000)) WriteByte svr,1 WriteString svr,name$ SendUDPMsg svr,Ip,7142 Repeat UDP() If KeyDown(17) Then MoveEntity player,0,0,2.5 : pz=pz+2.5 : move2=2.5 MoveEntity skybox,0,0,2.5 If Not Animating(player) Then Animate player,1,0.3,1,1 aktiv=1 EndIf EndIf If KeyDown(31) Then MoveEntity player,0,0,-2.5 : pz=pz-2.5 : move2=-2.5 MoveEntity skybox,0,0,-2.5 If Not Animating(player) Then Animate player,1,-0.3,1,1 aktiv=1 EndIf EndIf If KeyDown(57) And pVy = 0 Then pVy = 3.5 If Not (KeyDown(17) Or KeyDown(31) Or KeyDown(57) Or MouseDown(1)) Then Animate player,0 aktiv=0 EndIf Until KeyHit(1) WriteByte svr,3 SendUDPMsg svr,Ip,7142 CloseUDPStream(svr) CloseUDPStream(listen_udp) End Function UDP() readsvr = RecvUDPMsg(svr) If readsvr <> 0 Then readav = ReadAvail(svr) If readav <> 0 Then rbyte = ReadByte(svr) Select rbyte Case 1 ;con p.Player = New Player p\ip = ReadInt(svr) p\port = ReadInt(svr) p\model = clientp name2$ = ReadString(svr) ;p\id = ReadInt(svr) Case 2 ;dis rIp = ReadInt(svr) port = ReadInt(svr) For p.Player = Each Player If p\ip = rIp And p\port = port Then FreeEntity p\model Delete p End If Next Case 3 rIp = ReadInt(svr) port = ReadInt(svr) For p.Player = Each Player If p\ip = rIp And p\port = port Then p\x# = ReadFloat(svr) p\y# = ReadFloat(svr) p\z# = ReadFloat(svr) p\pitch = ReadInt(svr) p\yaw = ReadInt(svr) p\roll = ReadInt(svr) p\aktiv = ReadByte(svr) End If Next End Select End If End If read_milli = MilliSecs()+32 For p.Player = Each Player PositionEntity p\model,p\x#,p\y#,p\z# RotateEntity p\model,p\pitch,p\yaw,p\roll If p\aktiv=1 Then Animate clientp,1 Else Animate clientp,0 EndIf Next ;Send If send_milli < MilliSecs() Then WriteByte svr,3 WriteFloat svr,EntityX(player) WriteFloat svr,EntityY(player) WriteFloat svr,EntityZ(player) WriteInt svr,pitch WriteInt svr,yaw WriteInt svr,roll WriteByte svr,aktiv SendUDPMsg svr,Ip,7142 send_milli = MilliSecs()+32 End If End Function Ich hoffe ihr könnt mir sagen warum! ![]() Mfg, N0X |
||
Projekte: |Tibario| http://www.blitzforum.de/worklogs/325/ | 5% |
![]() |
Tankbuster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Vielleicht liegt es daran, dass du pro Schleifendurchlauf nur eine Nachricht aus dem Stream ließt. D.h. Wenn der Client mehr Nachrichten schickt, als der Server auslesen kann, kommt es zu einem Datenstau. | ||
Twitter
Download Jewel Snake! Windows|Android |
![]() |
N0X |
![]() Antworten mit Zitat ![]() |
---|---|---|
Daran kann es eig. nicht liegen, da es ohne die Übermittelung und Auslesung von "p\aktiv" und "aktiv" klappt!
Deswegen war ich verwundert ... Mfg, N0X[/code] |
||
Projekte: |Tibario| http://www.blitzforum.de/worklogs/325/ | 5% |
![]() |
Tankbuster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Finales Edit....: ![]() Was bezeichnest du als schleppend? Kommen die Pakete erst nach ein paar Sekunden an? |
||
Twitter
Download Jewel Snake! Windows|Android |
- Zuletzt bearbeitet von Tankbuster am Sa, Feb 14, 2009 17:49, insgesamt einmal bearbeitet
![]() |
N0X |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Bewegungen sind schleppend, also zu verzögert.
Das "p\aktiv" Paket hat die Aufgabe zu sagen ob sich der Client bewegt, tut er das soll eine Animation abgespielt werden. (nicht im Code oben vorhanden) ![]() |
||
Projekte: |Tibario| http://www.blitzforum.de/worklogs/325/ | 5% |
![]() |
Tankbuster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich kenne es nur, dass die Bewegungen ruckelig sind, wenn man Integer als Floats versendet. Aber Zeitverzögerung. Auf den ersten blick hab ich noch nichts finden können, aber ich shcau mir jetzt alles nochmal in Ruhe an.
EDIT: Testest du alles auf einem PC, der vielleicht damit einfach überfordert ist (CPU-Auslastung 100%, ect)? |
||
Twitter
Download Jewel Snake! Windows|Android |
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
N0X hat Folgendes geschrieben: Daran kann es eig. nicht liegen[...]
Es ist aber trotzdem falsch, pro Schleifendurchlauf nur ein Paket auszulesen. Schliesslich sendet jeder Teilnehmer alle 32 Millisekunden wieder ein Paket (das ist übrigens zu oft), was alle 2 Frames ist - und pro Frame liest du eine Nachricht aus. Bereits wenn zwei Clients im Spiel sind, führt das unweigerlich zu Datenstau. Also: Das Auslesen der Nachrichten in eine Schleife packen, die erst aufhört, wenn ReadAvail null ist. |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
![]() |
Tankbuster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Der Server läuft nur mit 40 FPS.
Und die Clients senden alle 32 Millisekunden eine Nachricht an den Server. Das kann irgendwie nicht gut gehen ![]() |
||
Twitter
Download Jewel Snake! Windows|Android |
c64 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi,
Übermittel nicht nur die Coordinaten deiner Objecte sondern auch deren beschleunigung (ob Dreh oder Normalbeschleunigung ist egal) du muss sie dann auch Local Updaten, sind zwar mehr Daten aber (je nach dem wie man es anstell viel mehr oder ein bischen mehr ![]() Warum ?! Weil wenn du nur die Coordinaten sendest, werden sie auch nur empfangen und mit jeden Update werden die Objecte auf diese Coordinaten gesetzt, da die Übertragung etwas dauert und auch dein Sender nur alle XX millisekunden sendet enstehen zwischen den einzelnen Coordinaten recht grosse differenzen die dann zu diesen "Sprüngen" führen. Hoffe das hilft ein wenig. mfg. C64 |
||
Betreten verboten! Kinder haften für ihre Eltern! |
![]() |
N0X |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ok, danke für die zahlreichen Antworten!
Das mit den "Millisecs+32" habe ich geändert, allerdings gibt es nur mit "+32" wirklich flüssige Bewegungsabläufe. Aber dazu muss ich ja nurnoch c64's Lösung hinkriegen, somit wäre das auch gelöst. @c64: Meinst du dann auch anstatt "Positionentity" "MoveEntity"? Mfg, N0X \\Edit Ich habe jetzt auch eine speed-Variable erstellt die ich übertrage und dann mit MoveEntity verwende. Funktioniert nur leider nicht besser. ![]() |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du must auch in den Zeiten wo keine Daten rein kommen, denoch weiterhin die Objekte lokal mit den letzten Geschwindigkeitsangaben fortbewegen. Das senden der einzelnen Daten muß dagegen wesentlich reduziert werden.
Das heisst: - nicht jedes Frame, sondern zum Beispiel nur 5 oder max. 10 mal in der Sekunde einmal Daten senden. Damit sollte kein Datenstau mehr auftretten. - Damit die Gegner dann aber nicht ruckeln, müssen die Zwischenschritte interpoliert werden, und zwar anhand der zuletzt gesetzten Geschwindigkeitsangaben einzelner Gegner. Der minimale Fehllauf der in diesen Zwischenschritten auftritt, fällt kaum auf. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
c64 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Jo genau ! ![]() @Nox sowie hectic es schrieb so meinte ich das auch. |
||
Betreten verboten! Kinder haften für ihre Eltern! |
![]() |
N0X |
![]() Antworten mit Zitat ![]() |
---|---|---|
Oh man...
Ohne Pseudo- oder Beispielcode versteh bzw. schaffe ich das nicht ... Tut mir Leid! Hoffe das jemand so lieb ist ![]() Mfg, N0X |
||
Projekte: |Tibario| http://www.blitzforum.de/worklogs/325/ | 5% |
![]() |
TimBo |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi Nox,
mache an die Stelle, wo ausgelesen wird, eine while wend hin. Pseudocode Code: [AUSKLAPPEN] while readavail(svr)
readsvr = RecvUDPMsg(svr) ...... wend das müsste gehen. ![]() Viele Grüße TimBo |
||
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31 hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht. |
![]() |
N0X |
![]() Antworten mit Zitat ![]() |
---|---|---|
Im Server oder im Client?
Oder in beiden? Nur im Server, ruckelt es immernoch! Mfg, N0X |
||
Projekte: |Tibario| http://www.blitzforum.de/worklogs/325/ | 5% |
![]() |
TimBo |
![]() Antworten mit Zitat ![]() |
---|---|---|
du musst es immer machen, wenn daten Empfangen werden, damit die kompletten Daten ausgelesen werden.
Wenn du keien While drum rum machst, kann es zum Datenstau kommen. ![]() Grüße TimBo |
||
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31 hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht. |
![]() |
Tankbuster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es ruckelt? ![]() Dann liegt es wohl daran, dass du Integer bei den Positionsangaben einfach als Floats versendet hast. ![]() Dadurch gibt es natürlich bei den Floats hinter dem Komma nur "00" , und das Objekt wir dann natürlich nicht so schön versetzt ![]() |
||
Twitter
Download Jewel Snake! Windows|Android |
![]() |
N0X |
![]() Antworten mit Zitat ![]() |
---|---|---|
Habe jetzt (glaube ich) alles beachtet allerdings *ruckelt* (Sprunghaft) es immernoch ...
Zur Kontrolle hier nochmal der Server-Code: [AUSKLAPPEN] Global timer=CreateTimer(40)
Graphics3D 640,480,16,2 ;--------------------------------------------------------------------------------------------| Type Player Field x#,y#,z# Field pitch,yaw,roll Field ip,port% Field aktiv Field speed End Type Type Gegner Field x#,y#,z# End Type Global svr = CreateUDPStream(7142) Global write_udp = CreateUDPStream(7143) Global send_milli#,read_milli#,readsvr,readav,rbyte,plycount,maxply While Not (KeyHit(1)) WaitTimer timer UDP() Wend CloseUDPStream(write_udp) CloseUDPStream(svr) End FreeEntity player Function UDP() readsvr = RecvUDPMsg(svr) If readsvr <> 0 Then readav = ReadAvail(svr) If readav <> 0 Then port = UDPMsgPort(svr) ip = UDPMsgIP(svr) rbyte = ReadByte(svr) Select rbyte Case 1 name$ = ReadString(svr) For p.Player = Each Player WriteByte svr,1 WriteInt svr,ip WriteInt svr,port SendUDPMsg svr,p\ip,p\port WriteByte svr,1 WriteInt svr,p\ip WriteInt svr,p\port WriteString svr,name$ SendUDPMsg svr,ip,port Next p.Player = New Player p\ip$ = ip p\port = port Print "Player Connected... "+name$ Case 2 For p.Player = Each Player If ip = p\ip And port = p\port Then Delete p End If Next For p.Player = Each Player WriteByte svr,2 WriteInt svr,ip WriteInt svr,port SendUDPMsg svr,p\ip,p\port Next Print "Player Disconnected..." Case 3 While ReadAvail(svr) For p.Player = Each Player If p\port = port And p\ip = ip Then p\x = ReadInt(svr) p\y = ReadInt(svr) p\z = ReadInt(svr) p\pitch = ReadInt(svr) p\yaw = ReadInt(svr) p\roll = ReadInt(svr) p\aktiv = ReadByte(svr) p\speed = ReadFloat(svr) End If Next Wend End Select End If End If read_milli = MilliSecs()+64 If send_milli < MilliSecs() Then For s.Player = Each Player For p.Player = Each Player If p\port <> s\port Then WriteByte svr,3 WriteInt svr,s\ip WriteInt svr,s\port WriteInt svr,s\x WriteInt svr,s\y WriteInt svr,s\z WriteInt svr,s\pitch WriteInt svr,s\yaw WriteInt svr,s\roll WriteByte svr,s\aktiv WriteFloat svr,s\speed SendUDPMsg svr,p\ip,p\port End If Next Next send_milli = MilliSecs()+128 End If End Function Function INT_IP(IP$) a1=Int(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a2=Int(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a3=Int(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a4=Int(IP$) Return (a1 Shl 24) + (a2 Shl 16) + (a3 Shl 8 ) +a4 End Function Und der Client-Code: [AUSKLAPPEN] Global timer=CreateTimer(40)
Graphics3D ax,ay,fx,2 SetBuffer BackBuffer() SeedRnd MilliSecs() ;--------------------------------------------------------------------------------------------| Type Player Field x#,y#,z# Field pitch,yaw,roll Field ip,port% Field model Field id Field typ$ Field aktiv Field speed End Type Type Gegner Field x#,y#,z# Field model End Type ;--------------------------------------------------------------------------------------------| server_ip$ = "127.0.0.1" sende_port = 7142 empfa_port = 7143 Global listen_udp = CreateUDPStream() Global svr = CreateUDPStream(Rnd(100,8000)) If Not listen_udp Or svr Then End EndIf Global Ip% = INT_IP(Input("IP: ")) Global name$ = Input("Name: ") WriteByte svr,1 WriteString svr,name$ SendUDPMsg svr,Ip,7142 ;--------------------------------------------------------------------------------------------| Repeat WaitTimer timer UDP() UpdateWorld() RenderWorld() Flip 0 Cls Until KeyHit(1) WriteByte svr,3 SendUDPMsg svr,Ip,7142 CloseUDPStream(svr) CloseUDPStream(listen_udp) End ;--------------------------------------------------------------------------------------------| Function UDP() readsvr = RecvUDPMsg(svr) If readsvr <> 0 Then readav = ReadAvail(svr) If readav <> 0 Then rbyte = ReadByte(svr) Select rbyte Case 1 ;con p.Player = New Player p\ip = ReadInt(svr) p\port = ReadInt(svr) p\model = clientp name2$ = ReadString(svr) ;p\id = ReadInt(svr) Case 2 ;dis rIp = ReadInt(svr) port = ReadInt(svr) For p.Player = Each Player If p\ip = rIp And p\port = port Then FreeEntity p\model Delete p End If Next Case 3 While ReadAvail(svr) rIp = ReadInt(svr) port = ReadInt(svr) For p.Player = Each Player If p\ip = rIp And p\port = port Then p\x# = ReadInt(svr) p\y# = ReadInt(svr) p\z# = ReadInt(svr) p\pitch = ReadInt(svr) p\yaw = ReadInt(svr) p\roll = ReadInt(svr) p\aktiv = ReadByte(svr) p\speed = ReadFloat(svr) End If Next Wend End Select End If End If read_milli = MilliSecs()+128 For p.Player = Each Player PositionEntity p\model,p\x#,p\y#,p\z# MoveEntity p\model,0,0,p\speed RotateEntity p\model,p\pitch,p\yaw,p\roll Next ;Send If send_milli < MilliSecs() Then WriteByte svr,3 WriteInt svr,EntityX(player) WriteInt svr,EntityY(player) WriteInt svr,EntityZ(player) WriteInt svr,pitch WriteInt svr,yaw WriteInt svr,roll WriteByte svr,aktiv WriteFloat svr,move2 SendUDPMsg svr,Ip,7142 send_milli = MilliSecs()+128 End If End Function Was kann ich denn noch tun? Mfg, N0X |
||
Projekte: |Tibario| http://www.blitzforum.de/worklogs/325/ | 5% |
![]() |
Tankbuster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hast du mal aus
Zitat: WriteInt svr,EntityX(player)
WriteInt svr,EntityY(player) WriteInt svr,EntityZ(player) Das gemacht: Zitat: WriteFloat svr,EntityX#(player)
WriteFloat svr,EntityY#(player) WriteFloat svr,EntityZ#(player) ![]() (dann natürlich auch beim Auslesen Floats auslesen ![]() |
||
Twitter
Download Jewel Snake! Windows|Android |
![]() |
N0X |
![]() Antworten mit Zitat ![]() |
---|---|---|
Natürlich 'hab ich das! (nur eben noch nicht geändert)
Klappt trotzdem nicht |
||
Projekte: |Tibario| http://www.blitzforum.de/worklogs/325/ | 5% |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group