UDP -.-
Übersicht

![]() |
biggicekeyBetreff: UDP -.- |
![]() Antworten mit Zitat ![]() |
---|---|---|
hallo,
ja schonwieder ein UDP problem deshalb auch in beginners. habe alle anderen UDP threads durch und habe auch ein lokal wunderbar funktionierendes UDP programm. das problem ist nur sobald ich es übers internet test funktioniert das verbinden eines neuen spielers nicht. hier der code: (ist ein modifiziertes sample) Code: [AUSKLAPPEN] Type spieler Field name$ Field IP End Type Graphics3D 640,480,32,2 SetBuffer BackBuffer() Print "Sample UDP Communications" ; Ask for mode Print "1-Server" Print "2-Client" Mode$=Input$(">") Select Mode$ Case "1" Udp_Port=4000 ; I/O Port Dest_Port=4000 AppTitle "Server on UDP Port "+Str(Udp_Port) Case "2" Udp_Port=4000 ; I/O Port Dest_Port=4000 AppTitle "Client on UDP Port "+Str(Udp_Port) Default Udp_Port=4000 ; I/O Port Dest_Port=4000 AppTitle "Server on UDP Port "+Str(Udp_Port) End Select ; Display all local user IP's ; Print "Local IPs:" For i=1 To CountHostIPs(GetEnv("localhost")) Print DottedIP(HostIP(i)) Next If mode$=2 Print "Enter Destination IP#: xxx.xxx.xxx.xxx";die IP des servers eingeben Dest_IP$=Input$(">") ; Convert to integer IP IP= Int_IP(Dest_IP$) ElseIf mode$=1 IP=HostIP(1) EndIf ; Allocate ports, get stream id's udp_stream=CreateUDPStream(Udp_Port) ; Stream erstellen name$=Input$("Name>") ;namen eingeben If mode$=1;servermodus s.spieler = New spieler s\name$=name$ s\ip=HostIP(1) ElseIf mode$=2;clientmodus WriteString(udp_stream,"hallo");hallo an server schicken WriteString(udp_stream,name$) SendUDPMsg udp_stream,IP,Dest_Port EndIf While Not KeyHit(1) If mode$=1;server ; Load UDP message into stream IP_rd=RecvUDPMsg(udp_stream) ; Test for messages in stream If IP_rd <> 0 Then ; Get received message message$=ReadString(udp_stream) If message$="hallo";hallo von neuem spieler s.spieler = New spieler;neuen spieler erstellen s\name$=ReadString(udp_stream) s\ip=IP_rd WriteString(udp_stream,"willkommenimspiel");bestätigung senden WriteString(udp_stream,name$) WriteString(udp_stream,IP_rd) SendUDPMsg udp_stream,IP_rd,Dest_Port EndIf EndIf ElseIf mode$=2;client ; Load UDP message into stream IP_rd=RecvUDPMsg(udp_stream) ; Test for messages in stream If IP_rd <> 0 Then ; Get received message message$=ReadString(udp_stream) If message$="willkommenimspiel";bestätigung vom server s.spieler = New spieler;server als spieler hinzfügen s\name$=ReadString(udp_stream) s\ip=IP_rd t.spieler = New spieler;eigenen spieler erstellen t\name$=name$ t\ip=ReadString(udp_stream) EndIf EndIf EndIf Flip Cls i=0 For s.spieler = Each spieler;aktuelle spieler im spiel Text 000,10+i,"name: "+s\name$ i=i+10 Text 000,10+i,"IP: "+DottedIP(s\ip) i=i+20 Next Wend ; Cleanup and terminate CloseUDPStream udp_stream ;-------------------------------------- ; FUNCTION: INT_IP(IP$) ; ; Returns integer value of a IP Address string ; IP$ Format n.n.n.n Function Int_IP(IP$) a1=val(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a2=val(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a3=val(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a4=val(IP$) Return (a1 Shl 24) + (a2 Shl 16) + (a3 Shl 8 ) +a4 End Function ;-------------------------------------- ; FUNCTION: VAL(STRING$) ; ; Returns integer value of a string Function val(String$) ac=String$ Return String$ End Function sollte sich selbst erklären. wird der servermodus gewählt erstellt dieser einen spieler(sich selbst) und wartet nur darauf das ein neuer spieler connectet. nun sollte ein client gestartet werden der das hallo und seinen namen an die IP des host schickt. empfängt der host das "hallo" erstellt er einen neuen spieler mit dem namen und speichert die IP. er antwortet mit einen "willkommen" mit seinem namen und der IP des clients. empfängt der host das willkommen erstellt er einen neuen spieler für den server mit dessen namen und dessen IP und einen neuen spieler für sich mit seinem namen und seiner IP die ihm der server mitgeschickt hat. in der ausgabe sehen nun beide sich selbst und sich gegenseitig jeweils name und ip. dieser test ist nur für 2 Spieler ausgelegt. wollten mehr joinen müsste der server jedesmal an alle spieler alle daten schicken damit jeder jeden kennt das hab ich einfach mal außen vor gelassen. teste ich dieses programm lokal, funktioniert es wunderbar. über inet jedoch nicht. ich hoffe jemand kann erkennen wo der fehler liegt. achtung! wollt ihr das programm lokal testen müsst ihr für ein und ausgang verschiedenen ports verwenden. dazu Code: [AUSKLAPPEN] Select Mode$ Case "1" Udp_Port=4000 ; I/O Port Dest_Port=4001 AppTitle "Server on UDP Port "+Str(Udp_Port) Case "2" Udp_Port=4001 ; I/O Port Dest_Port=4000 AppTitle "Client on UDP Port "+Str(Udp_Port) Default Udp_Port=4000 ; I/O Port Dest_Port=4001 AppTitle "Server on UDP Port "+Str(Udp_Port) End Select an entsprechender stelle einfügen |
||
#45 www.icekeyunlimited.de www.starcrusade.de
Gewinner BCC#17 !!! mit dotkiller Nothing more to register - you've cleaned us out![/size] |
ChristianK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wenn du einen Router benutzt, musst du die angegebenen Ports dort freischalten, zumindest beim Server. | ||
![]() |
biggicekey |
![]() Antworten mit Zitat ![]() |
---|---|---|
also nach einem test bei dem der server seinen port 4000 geöffnet hatte funktionierte es serverseitig mittlerweile. d.h. der server hat sowohl sich selbst als auch den client gesehen.
der client jedoch keinen von beiden. d.h. dass "hallo" vom client kam beim server an. nur scheinbar das"willkommenimspiel" vom server kam beim client nicht an. dies liegt wahrscheinlich auch an dem router, wobei ich dachte, dass durch das "hallo" ein loch in der firewall sein sollte durch welches der server antworten kann. so wurde es mir zumindest mal erklärt. wie sieht das in der praxis aus? |
||
#45 www.icekeyunlimited.de www.starcrusade.de
Gewinner BCC#17 !!! mit dotkiller Nothing more to register - you've cleaned us out![/size] |
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Denke mal das Problem ist schon der Router. Du sagst zwar beim Client dass er auf einem bestimmten Port (4000) abhören soll. Doch das gilt nur hinter dem Router, im lokalen Netz. Der Router nimmt gegen Aussen einen völlig anderen Port, und merkt sich welcher externe Port mit welchem internen Port verknüpft wird. Der interne ist dann also 4000 und der externe könnte z.B. 6000 sein. Da der Server aber an 4000 schickt ist klar, dass der Client nichts bekommt. Der Server muss dann an 6000 schicken, der Router beim Client leitet es dann wieder an Port 4000 weiter. Glaube mit UDPMsgPort(udp_stream) bekommst du den effektiven Port des Clients raus. Am besten speicherst du den neben der IP auch gleich im Spieler Type.
Kleines Beispiel wie der Router das macht: Server: Interne Adresse: 192.168.0.2:4000 Externe Adresse (Router): 84.55.55.55:4000 Mit dem Port Forwarding kannst du ja den externen Port angeben, deshalb stimmts beim Server. Client: Interne Adresse: 192.168.1.4:4000 Externe Adresse (Router): 84.22.22.22:7042 Port Adress Translation sucht sich selber einen freien externen Port, und ordnet ihn dem internen Port zu. Für den Server sieht es dann also so aus, als ob der Client die IP 84.22.22.22 hätte und mit Port 7042 sendet. Der Server muss also zum Antworten dahin senden. |
||
![]() |
biggicekey |
![]() Antworten mit Zitat ![]() |
---|---|---|
hey danke jolinah, der post hat wirklich geholfen.
anfragen an den server sende ich jetzt immer an port 4000 welcher beim server ja geöffnet ist und lasse den port des clients per zufall generieren. der server speichert sich den port des clients wie beschrieben und antwortet auf diesen. schon funktionierts soweit. falls noch jemand ne idee hat auch das port öffnen des servers unnötig zu machen immer her damit. hier der soweit funktionierende code: Code: [AUSKLAPPEN] Type spieler
Field name$ Field IP End Type Graphics3D 640,480,32,2 SetBuffer BackBuffer() Print "Sample UDP Communications" ; Ask for mode Print "1-Server" Print "2-Client" Mode$=Input$(">") Select Mode$ Case "1" Udp_Port=4000 ; I/O Port Dest_Port=4000 AppTitle "Server on UDP Port "+Str(Udp_Port) Case "2" Udp_Port=4000 ; I/O Port ;!!!!!!!!!wird nichtmehr beachtet im weiteren code!!!!!!!!!!!!!! Dest_Port=4000 AppTitle "Client on UDP Port ";+Str(Udp_Port) Default Udp_Port=4000 ; I/O Port Dest_Port=4000 AppTitle "Server on UDP Port "+Str(Udp_Port) End Select ; Display all local user IP's ; Print "Local IPs:" For i=1 To CountHostIPs(GetEnv("localhost")) Print DottedIP(HostIP(i)) Next Print "deine externe IP" Print getip$() If mode$=2 Print "Enter Destination IP#: xxx.xxx.xxx.xxx";die IP des servers eingeben ;Dest_IP$="91.4.112.214"; Dest_IP$=Input$(">") ; Convert to integer IP IP= Int_IP(Dest_IP$) ElseIf mode$=1 IP=HostIP(1) EndIf ; Allocate ports, get stream id's If mode$=1 udp_stream=CreateUDPStream(Udp_Port) ; Stream erstellen Else udp_stream=CreateUDPStream() ; Stream erstellen EndIf name$=Input$("Name>");"biggi";Input$("Name>") ;namen eingeben If mode$=1;servermodus s.spieler = New spieler s\name$=name$ s\ip=HostIP(1) ElseIf mode$=2;clientmodus WriteString(udp_stream,"hallo");hallo an server schicken WriteString(udp_stream,name$) SendUDPMsg udp_stream,IP,Dest_Port EndIf While Not KeyHit(1) If mode$=1;server ; Load UDP message into stream IP_rd=RecvUDPMsg(udp_stream) Dest_Port=UDPMsgPort (udp_stream) ; Test for messages in stream If IP_rd <> 0 Then ; Get received message message$=ReadString(udp_stream) If message$="hallo";hallo von neuem spieler s.spieler = New spieler;neuen spieler erstellen s\name$=ReadString(udp_stream) s\ip=IP_rd WriteString(udp_stream,"willkommenimspiel");bestätigung senden WriteString(udp_stream,name$) WriteString(udp_stream,IP_rd) SendUDPMsg udp_stream,IP_rd,Dest_Port EndIf EndIf ElseIf mode$=2;client ; Load UDP message into stream IP_rd=RecvUDPMsg(udp_stream) ; Test for messages in stream If IP_rd <> 0 Then ; Get received message message$=ReadString(udp_stream) Print message$ WaitKey() If message$="willkommenimspiel";bestätigung vom server s.spieler = New spieler;server als spieler hinzfügen s\name$=ReadString(udp_stream) s\ip=IP_rd t.spieler = New spieler;eigenen spieler erstellen t\name$=name$ t\ip=ReadString(udp_stream) ElseIf message$="hallo";hallo von neuem spieler test=1 Print "hallo zurückgekommen" WaitKey() EndIf EndIf EndIf Flip Cls i=0 For s.spieler = Each spieler;aktuelle spieler im spiel Text 000,10+i,"name: "+s\name$ i=i+10 Text 000,10+i,"IP: "+DottedIP(s\ip) i=i+20 Next Text 200,10,"t: "+test Wend ; Cleanup and terminate CloseUDPStream udp_stream ;-------------------------------------- ; FUNCTION: INT_IP(IP$) ; ; Returns integer value of a IP Address string ; IP$ Format n.n.n.n Function Int_IP(IP$) a1=val(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a2=val(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a3=val(Left(IP$,Instr(IP$,".")-1)):IP$=Right(IP$,Len(IP$)-Instr(IP$,".")) a4=val(IP$) Return (a1 Shl 24) + (a2 Shl 16) + (a3 Shl 8 ) +a4 End Function ;-------------------------------------- ; FUNCTION: VAL(STRING$) ; ; Returns integer value of a string Function val(String$) ac=String$ Return String$ End Function Function getip$() Local stream = OpenTCPStream("www.wieistmeineip.de",80), income$,ip$ WriteLine( stream, "GET http://www.wieistmeineip.de HTTP/1.0" ) WriteLine( stream, "Host: www.wieistmeineip.de" ) WriteLine( stream, "Accept: */*" ) WriteLine( stream, Chr$( 10 ) ) Repeat income = ReadLine$(stream) ;hier wird aus dem einkommenden zeichen dann die stelle rausgesucht wo die ip beginnt die chr$(34) stellen nur " dar If Instr(Income,"<h1 class="+Chr$(34)+"ip"+Chr$(34)+">") Then ip$=Mid$(income,Instr(income,"<h1 class="+Chr$(34)+"ip"+Chr$(34)+">")+Len("<h1 class="+Chr$(34)+"ip"+Chr$(34)+">")) ip$=Mid$(ip$,1,Instr(ip$,"</h1>")-1) End If Until Eof(stream) Return ip$ End Function |
||
#45 www.icekeyunlimited.de www.starcrusade.de
Gewinner BCC#17 !!! mit dotkiller Nothing more to register - you've cleaned us out![/size] |
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Beim Server muss man das, soweit ich weiss, leider immer machen. Ohne Angaben kann der Router ja nicht wissen was er machen soll. Das heisst man übergibt die Aufgabe an einem Port abzuhören dem Router, und der leitet alles an den PC weiter. Die PCs selber sind gar nicht am Internet angeschlossen, deshalb bringt es nichts wenn sie einen Port abhören (ohne Portforwarding). Nur dank der Weiterleitung des Routers ist ihnen die Kommunikation mit dem Internet überhaupt möglich. | ||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group