UDP -.-

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

biggicekey

Betreff: UDP -.-

BeitragDo, Jun 21, 2007 22:56
Antworten mit Zitat
Benutzer-Profile anzeigen
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


Print
; 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

BeitragDo, Jun 21, 2007 23:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn du einen Router benutzt, musst du die angegebenen Ports dort freischalten, zumindest beim Server.

biggicekey

BeitragMo, Jun 25, 2007 13:27
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jun 25, 2007 16:13
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Jun 26, 2007 12:58
Antworten mit Zitat
Benutzer-Profile anzeigen
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


Print
; 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

BeitragDi, Jun 26, 2007 16:56
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group