Mal ein paar Fragen zu UDP (inzwischen auch TCP)
Übersicht

Gehe zu Seite Zurück 1, 2, 3 Weiter
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Gibt es die MAV denn nur, wenn Clients zum Server verbunden sind, und dieser dann schließt? Sollte dies der Fall sein, schließe doch einfach gegen Ende alle Verbindungen mit den Clients und erst dann den Socket, auf dem dein Server auf Verbindungen wartet.
Wenn ich was verwechselt habe, ignorieren. ![]() |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hast du Debug an? Ich denke da sollte eine etwas genauere Information kommen. Vermutlich ein Stream does not exist oder so.
Hab hier mal ein Beispiel geschrieben, damit funktionierts bei mir zumindest. Mann kann auch Streamprobleme mit Eof Abfangen damit das Programm nicht abstürzt wenn ein Client das Fenster schliesst statt sich richtig abzumelden: Server: Code: [AUSKLAPPEN] ;Type für die Clients
Type client Field stream Field name$ End Type ;Server erstellen tcp = CreateTCPServer(1010) If tcp = 0 Then Print "Server starten fehlgeschlagen." End Else Print "Server gestartet auf Port 1010." EndIf ;Hauptschleife While Not KeyHit(1) ;Client-Streams annehmen stream = AcceptTCPStream(tcp) If stream c.client = New client c\stream = stream c\name$ = ReadString(c\stream) Print "Client " + c\name$ + " eingeloggt." EndIf ;Jeden Client durchgehen... For c.client = Each client ;Wenn Eof -1 oder 1 ist kann nichts mehr mit dem Stream gemacht werden ef = Eof(c\stream) If ef = -1 Then Print "Verbindungsproblem mit Client: " + c\name$ WaitKey() CloseTCPStream(c\stream) Delete c ElseIf ef = 1 Print c\name$ + " hat den Stream geschlossen ohne sich abzumelden." WaitKey() CloseTCPStream(c\stream) Delete c ;Wenn kein Stream-Fehler wird geschaut ob Daten da sind... ElseIf ReadAvail(c\stream) msg$ = ReadString(c\stream) pos = Instr(msg$, " ") If pos > 0 cmd$ = Left(msg$, pos-1) Else cmd$ = msg$ EndIf Select cmd$ ;Wird Logout empfangen so schliesst man den Stream und löscht den Client Case "LOGOUT" Print "Client " + c\name$ + " ausgeloggt." CloseTCPStream(c\stream) Delete c ;Sender der Client ein Print gibt man den Text aus.. Case "PRINT" Print "Client " + c\name$ + " sendet: " + Mid(msg$, pos+1) End Select EndIf Next Wend ;Falls noch clients da sind Streams schliessen For c.client = Each client ef = Eof(c\stream) ;Nur schreiben wenn kein Stream-Fehler If ef = 0 WriteString(c\stream, "KICK") EndIf CloseTCPStream(c\stream) Delete c Next ;Server beenden CloseTCPServer(tcp) End Client Code: [AUSKLAPPEN] ;TCP Verindung öffnen
tcp = OpenTCPStream("localhost", 1010) If tcp = 0 Then Print "Verbindung mit dem Server fehlgeschlagen." WaitKey() End Else Print "Eine Verbindung mit dem Server wurde hergestellt." EndIf ;Clientname name$ = "Test-Client" WriteString(tcp, name$) ;Variablen zum Beenden quit = False send_quitmsg = True ;gibt an ob die Logout Message beim Beenden an den Server geschickt wird. ;Hauptschleife While (Not KeyHit(1)) And (Not quit) ;Auf Stream-Fehler prüfen.. ef = Eof(tcp) If ef = -1 Print "Verbindungsproblem. Ende." WaitKey() send_quitmsg = False quit = True ElseIf ef = 1 Print "Verbindungsproblem. Ende" WaitKey() send_quitmsg = False quit = True ;Kein Fehler, schauen ob Daten verfügbar sind.. ElseIf ReadAvail(tcp) msg$ = ReadString(tcp) Select msg$ ;Bei KICK Meldung vom Server beenden wir den Client. Case "KICK" Print "Der Server wurde heruntergefahren." WaitKey() ;Bei einem kick braucht der Client nicht mehr Bye zu sagen (send_quitmsg) send_quitmsg = False quit = True End Select EndIf ;Leertaste sendet ein Kommando an den Server. If KeyHit(57) Then WriteString(tcp, "PRINT Hallo Welt!") EndIf Wend ;Quitmessage senden If send_quitmsg Then ef = Eof(tcp) ;Nur wenn kein Verbindungsfehler vorhanden.. If ef = 0 WriteString(tcp, "LOGOUT") EndIf EndIf ;Stream schliessen CloseTCPStream(tcp) End Hoffe das hilft dir weiter ![]() |
||
![]() |
Smokie |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe jetzt mal ne dumme Frage:
Ich habe zwar gelsen, dass Dim Felder für UDP etc. besser sind, weil die schneller sind, aber ich komme mit Types besser zurecht. Würde es sich also lohnen das Projekt mit Internet mit Types zu machen, die sind ja langsamer. Und wenn das oaky wäre bis zu welcher Menge an Daten kann man Types benutzen ohne das es "ruckelt". Danke Smokie |
||
M-Soft Studios Mit selbst gemachtem Forum!!!
Unbequem lebt's sich schwer. Musik macht erst Spaß, wenn man sie mit 2,8 facher Geschwindigkeit hört Zuletzt bearbeitet von Smokie am Fr Jan 01, 1888 51:58 PM, insgesamt 1000-mal bearbeitet |
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@Mau
Nox hat recht, Du musst erst alle Clientstreams mit CloseTCPStream schließen(auch wenn diese bereits Clientseitig abgebrochen wurden), erst dann kannst Du CloseTCPServer verwenden. So gibt es zumindest bei mir keine Probleme @Smokie Keine Ahnung wo Du das gehört hast, jedenfalls ist es Unsinn. Mit einem Typesystem dürfte das Realisieren der Netzwerkunterstützung sogar etwas leichter ausfallen. |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
Mau |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Zitat: @Mau
Nox hat recht, Du musst erst alle Clientstreams mit CloseTCPStream schließen(auch wenn diese bereits Clientseitig abgebrochen wurden), erst dann kannst Du CloseTCPServer verwenden. So gibt es zumindest bei mir keine Probleme Danke Leute - CloseTCPServer scheint jetzt zu klappen. Ihr hattet recht. Der Host muß zuerst den Stream zu jedem Client kappen, bevor der Server geschlossen wird. Ausserdem muß jeder Client den Strom von seiner Seite aus auch mit CloseTCPStream kappen. Nur so funktioniert das bei mir (endlich mal!). @smokie: Das ist Quatsch. Types sind nur minimal langsamer - jedenfalls so gering, daß sich ein Unterschied höchstens in einer Schleife auswirkt, die man zigtausendmal pro Frame durchläuft. Den Unterschied kannst du in 99% aller Fälle getrost ignorieren. Ist schlicht nicht bemerkbar. Ich denke, solche Sachen bringen immer wieder sog. "Old School"-Neandertaler auf, die sich einfach nicht umgewöhnen wollen (oder können). Meine Meinung ![]() |
||
Alles muss, nichts kann! |
![]() |
Smokie |
![]() Antworten mit Zitat ![]() |
---|---|---|
Juhu wenn das so ist versuche ich auch mal ein kleines Chat-programm zu schreiben. Ich hatt nähmlich immer so ein rpoblem mit der verwaltung von den Dims
Danke Grüße Smokie |
||
M-Soft Studios Mit selbst gemachtem Forum!!!
Unbequem lebt's sich schwer. Musik macht erst Spaß, wenn man sie mit 2,8 facher Geschwindigkeit hört Zuletzt bearbeitet von Smokie am Fr Jan 01, 1888 51:58 PM, insgesamt 1000-mal bearbeitet |
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Mau hat Folgendes geschrieben: Danke Leute - CloseTCPServer scheint jetzt zu klappen. Ihr hattet recht. Der Host muß zuerst den Stream zu jedem Client kappen, bevor der Server geschlossen wird.
Vielleicht sollte man noch kurz anmerken, wieso das so ist: Über Blitz wird's nicht ganz deutlich, was Sockets eigentlich sind btw. wie und wann man sie wofür benutzt. ![]() |
||
Mau |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Tja, wenn aber dann ein Client sein Fenster einfach schliesst, ist der Host gearscht -dann schmiert das Game beim Schliessen des Servers ab -einzige Lösung wäre hier vielleicht, regelmässig ein Ping anzufordern, ob der Client noch da ist. Kommt keins, wird der Stream geschlossen.
Noch eine Frage in Sachen IP: ich möchte in meinem Game dem Host gleich seine IP anzeigen, damit auch unbedarfte Spieler die gleich ihren Freunden mitteilen können. Ich ermittle die IP des Hosts momentan so: Code: [AUSKLAPPEN] CountHostIPs("") HostIP = HostIP(1) HostIP_Str$ = DottedIP$( HostIP(1) ) Funktioniert auch -AAABER: woher weiss man denn, welches die lokale, und welched die Internet-IP ist? |
||
Alles muss, nichts kann! |
- Zuletzt bearbeitet von Mau am Mi, Sep 21, 2005 17:44, insgesamt einmal bearbeitet
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Mau hat Folgendes geschrieben: Tja, wenn aber dann ein Client sein Fenster einfach schliesst, ist der Host gearscht -dann schmiert das Game beim Schliessen des Servers ab -einzige Lösung wäre hier vielleicht, regelmässig ein Ping anzufordern, ob der Client noch da ist. Kommt keins, wird der Stream geschlossen.
Auch wenn du beim Schließen der Server-Applikation alle Sockets der Clients schließt? Kann ich mir schon fast nicht mehr vorstellen. Ansonsten: Ein Ping/Pong ist Pflicht! Ein Host würde z.B. nicht mitbekommen, wenn ein Client sein Netzwerkkabel zieht und sofort die Internetverbindung verliert. Da bleibt dem Client nämlich keine Möglichkeit mehr, dem Host mitzuteilen, dass er grad stirbt. ![]() Also immer schön pingen, und z.B. nach drei nicht mehr empfangenen Pongs Verbindung trennen und Socket schließen (vom Client, natürlich). Mau hat Folgendes geschrieben: Woher weiss man nun, was eine interne IP und was z.B. eine Internet-IP ist? Und wie viele IPs kann ein Host haben?
Das weiß man so leicht natürlich nicht. ![]() Verbinde beispielweise nach "checkip.dyndns.org" per TCP auf Port 80 und sende ein einfaches HTTP-Request: GET / HTTP/1.1 (zwei Leerzeilen) Als Antwort wird der Host dir deine IP (mitsamt einigem Headerkram, den du getrost ignorieren kannst) mitteilen. Schaue dir die Antwort auf deinen Request einfach mal an. Daraus wirst du ableiten können, wie du die IP rausfiltern kannst. |
||
Mau |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Niaaa... ich linke ungern auf irgendwelche Seiten. Irgendwann gibt's die nicht mehr und es hagelt hässliche Fehlermeldungen oder es kommt nix. Lieber unabhängig bleiben ![]() ![]() EDIT: Also, diese "Einfrierer" machen mir wirklich sorgen -jedesmal, wenn z.B. der Host eine Nachricht (TCP) empfängt, stockt alles für ein, zwei Sekunden. Das ist ja furchtbar! ![]() |
||
Alles muss, nichts kann! |
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Okay, die Seiten könnten natürlich irgendwann offline gehen (was beim Fall dyndns.org wahrscheinlich noch SEHR lange dauern könnte ![]() ![]() Eine andere Möglichkeit wäre, den Benutzer das einfach selbst wählen lassen zu können. Vielleicht hat der Jemand eine dynamische Host, deren Name du zu einer IP auflösen kannst. |
||
Mau |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ja klar, die IP kann der Host schon nach Belieben selbst eingeben -ich möchte damit nur ein wenig Hilfestellung geben, falls der User keinen Schimmer hat, was für eine IP er hat (oder damit er nicht extra nachsehen muss). Das passt schon.
Was mir im Moment aber Angst macht, ist dieses ständige "Einfrieren" des Hosts, wenn z.B. eine Client-Nachricht reinkommt (Nachrichteneingang wird gelesen mit ReadAvail() -und die Nachrichten sind wirklich nicht groß, ein ID-Byte und dann halt noch ein Chat-String). Aber jedesmal hält das komplette Programm für ein, zwei Sekunden an, wenn eine Nachricht reinkommt. Allerdings nur bei Verbindung über Internet. Über LAN ist das auch noch bemerkbar, aber nicht ganz so stark. Dagegen gibt es wohl keine Lösung, oder? |
||
Alles muss, nichts kann! |
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also, ich habe es jetzt mal selbst ausprobiert. Konnte natürlich nur lokal testen, da aber ohne jegliche Geschwindigkeitseinbußen. Teste es doch einfach mal bei dir. Hier die beiden Quellcodes (einmal ein Serverprogramm und einmal ein Clientprogramm):
Server: BlitzBasic: [AUSKLAPPEN]
Client: BlitzBasic: [AUSKLAPPEN]
Edit: Ich denke übrigens, dass du möglicherweise nicht beachtet hast, ein vernünftiges Timeout zu setzen. Probiert habe ich nicht, ob eine "0" auch zulässig ist. Bei ersten Tests funktionierte dies nicht. |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du kannst auch ohne Ping/Pong testen ob ein Socket nicht mehr verbunden ist mit Eof(). So erkennst du beim Client auch ob das Programm richtig beendet oder ob das Fenster geschlossen wurde.
Siehe Code oben ![]() |
||
Mau |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Bei einem Text-Screen erkennt man Ruckler doch kaum ![]() In meinem Game ist ziemlich viel Bewegung auf dem Screen (animierte 3D-Figuren, Laufschrift, Kamera usw.). Sobald eine Nachricht reinkommt, fällt das da brutal auf. Das kann man mit einem Text-Programm ja kaum merken -der schreibt den Text ja erst, wenn er fertig ist. Es liegt auch nicht an einer Schleife, die ich zu lange durchlaufe. Die einzige Schleife, die ich in der Empfangs-Funktion habe, ist das While ReadAvail( ) ... Wend , es muß an den TCP-Funktionen liegen. @Jolinah: Du meinst, mann könne statt einem Ping auch AcceptTCPStream( ) nutzen, um zu sehen, ob ein CLient noch da ist? Ich denke, daß liefert nur einen Wert, wenn gerade eine Nachricht vom Client eintrifft, also nicht ständig. Als Ping-Ersatz könnte man es ja nur nutzen, wenn es ständig einen Wert liefert, so lange eine Verbindung offen ist. Oder meintest du etwas anderes? |
||
Alles muss, nichts kann! |
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wenn es bei der Textvariante nicht ruckelt, dann wird es höchstwahrscheinlich nicht an der Datenübertragung von TCP liegen. Mache doch erstmal Tests NUR mit TCP, wie mein Beispiel. Nur mit etwas mehr Belastung. Wenn die Tests ebenfalls alle funktionieren, weißt du vielleicht mehr.
Edit: Bist du sicher, dass du einen korrekten Timeout zu verwendest? |
||
Mau |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das witzige ist ja, daß TCPTimeOuts überhaupt gar keinen Effekt zu haben scheint. Das bringt keinen Unterschied. Ich frage mich, ob das nicht einfach nur ein "Fake"-Befehl ist ![]() |
||
Alles muss, nichts kann! |
Nox |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ist es mit Sicherheit nicht. Bei mir hat die Funktion Effekt gezeigt. Ohne den Befehl in meinem Code wurde jeweils 10 Sek. gewartet, ob Daten eintreffen. | ||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
@Mau: Ich meinte die Eof()-Funktion nicht AcceptTCPStream().
Bei TCP wird ja ReadAvail() benutzt zum schauen wieviel Daten angekommen sind, mit Eof() kann man hingegen Testen ob das Socket noch verbunden ist. Wenn Eof() -1 zurück gibt dann war es eine unsaubere Trennung (Trennung ohne CloseTCPStream()), bei 1 war es eine saubere Trennung. Also kannst du bevor du was machst immer Abfragen ob das Socket noch verbunden ist. PS: Kann mir irgendwie nicht vorstellen dass es an TCP liegt. Klar TCP ist langsamer als UDP, aber so extrem ist es nun auch wieder nicht, zumindest solange man nicht Byte für Byte sendet, weil da immer der ganze TCP Header mit verschickt wird. Wollte früher mal nen 3D-Chat machen wo sich die Chatter als 3D-Charakter bewegen können usw.. Hab da TCP und UDP kombiniert. Bewegungsupdates mit UDP und Chat etc. mit TCP. Ruckler seitens TCP hatte ich aber keine, höchstens von der Grafik her ![]() Das Verbinden kann manchmal ne Weile dauern, aber wenn man einmal verbunden ist treten zumindest bei mir keine solchen Wartezeiten mehr auf. |
||
Mau |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich habe jetzt mal das
While ReadAvail(Stream) > 0 gegen While EOF(Stream) = 0 getauscht -was ja eigentlich funktionieren müsste, oder? Seltsamerweise hängt sich das Spiel dann in einer Endlosschleife auf, selbst wenn keine Daten reinkommen. Kann es sein, daß ein vorhandener Stream IMMER ein EOF 0 liefert, auch wenn keine Daten von ihm kommen? Laut Manual müsste EOF doch nur 0 liefern, wenn Daten aus dem Strom zu lesen sind und 1, wenn er "leergelesen" ist, oder? |
||
Alles muss, nichts kann! |
Gehe zu Seite Zurück 1, 2, 3 Weiter
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group