[TCP] Verbindungsprobleme
Übersicht

![]() |
DerKeksBetreff: [TCP] Verbindungsprobleme |
![]() Antworten mit Zitat ![]() |
---|---|---|
hey leute,
habe mal wieder ein TCP-Problem... habe mich mal wieder an nem Chat versucht und soweit alles ok... bis auf 2 probleme.. 1) Habe insgesamt 4 "actions" (_new_user, _in_msg, _leave_user und _server_close) der server liest die ersten 3 aus und kann die letzte senden (logisch). das problem liegt darin, dass er die "_new_user" actions ohne prbleme behandelt, die entsprechenden Types anlegt und allen verbundenen clients bescheid gibt. nur wenn einer eine nachricht schreibt ("_in_msg") oder den chat verlässt ("_leave_user") werden diese beiden actions zwar am client abgesendet (mit debuglog geprüft) aber kommen am server nicht an (auch so geprüft) ich kann clints verbinden soviele ich will, es kommt immer _new_user an im stream aber die anderen beiden actions kommen nie am server an.... habe echt kaum ne ahnung woran es liegt dass nur eine von 3 actions geprüft/behandelt wird... 2) das ende des servers: ESC -> Message an Alle (Server closing) -> Server closen (CloseTCPServer) -> End die nachricht von wegen server closing kommt bei den clients an, nur direkt nach dem senden dieser nachrichten bekommen ich am Server nen MAV ... Wenn ich das im debugmodus mache kriegen ich nen c-runtime error irgendwas mit program terminating... unexpected oder so. kann ich bei bedarf nen screen von machen, denn es war soweit ich weiss eine fehlernummer bei. hier noch ein screen : 2 mal verbunden und geschrieben, nur die connects kamen am server an.. http://file.qip.ru/download/69...7-74f2c4f8 (einmal aufs bild klicken zum anzeigen und dann rechtsklick -> grafik anzeigen. ist QIP photo hosting ![]() bei bedarf poste ich auch code, nur bescheid sagen ![]() hoffe ihr könnt mir da irgendwie helfen... |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es wird schwierig, dir ohne Code helfen zu wollen. Und das stückchen Code, dass man auf dem Screen sieht, hilft mir auch nicht gerade weiter.
Nun... ich rate einfach mal wild drauflos: zu 1) das klingt ganz so, als ob du für jede IF-Abfrage den Nachrichtentypen neu auslesen würdest... Also würde nur beim ersten If ReadLine auch der Nachrichtentyp abgefragt, die anderen würden bereits auf irgendwelche Daten zugreiffen wollen. Zudem würde ich dir empfehlen, die Nachrichtentypen nicht per Line, sondern per Byte zu definieren. Spart schon mal ein wenig Netzwerkverkehr... zum 2) kann ich dir leider grad absolut nicht helfen =/ habe ich nämlich noch nie erlebt. mfG |
||
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 |
![]() |
DerKeks |
![]() Antworten mit Zitat ![]() |
---|---|---|
okay dann geb ich euch mal den code ![]() so schauts im moment beim server aus : Code: [AUSKLAPPEN] AppTitle "TCP-Chat | Server"
Type user Field ip$, name$, stream, admin End Type port = 200 Print "|= Server wird gestartet..." stream = CreateTCPServer(port) If stream <> 0 Print "|= Server gestartet!" CountHostIPs("localhost") Print "|+ IP : " + DottedIP$(HostIP(1)) Print "|+ Port : " + port Else Print "|= Server konnte nicht gestartet werden." Print "Prüfen sie die Firewall-/Rooter-Einstellungen" Print "*Taste drücken*" WaitKey End EndIf Color 000, 255, 000 Print "==============================" Print "===== Online =====" Print "==============================" Color 255, 255, 255 Print "|= Suche Verbindungen..." Print "==============================" While Not KeyHit(1) in = AcceptTCPStream(stream) If in in_msg$ = ReadLine(in) DebugLog "in_msg$ : "+in_msg$ Select in_msg$ Case "_new_user" ip$ = ReadLine$(in) name$ = ReadLine$(in) admin = ReadLine(in) u.user = New user u\ip$ = ip$ u\name$ = name$ u\stream = in u\admin = admin Print "[SYS] - New User '"+name$+"' joined the room" If admin = 1 Print "[SYS] - He is Admin" Else Print "[SYS] - He is User" EndIf For o.user = Each user If o\stream <> in WriteLine o\stream, "_new_user" WriteLine o\stream, name$ EndIf Next in_msg$ = ReadLine(in) Case "_in_msg" sender$ = ReadLine(in) nachr$ = ReadLine(in) Print "[MSG] - <"+sender$+"> : "+nachr$ For o.user = Each user If o\stream <> in WriteLine o\stream, "_in_msg" WriteLine o\stream, sender$ WriteLine o\stream, nachr$ EndIf Next in_msg$ = ReadLine(in) Case "_leave_user" leaver$ = ReadLine$(in) reason$ = ReadLine$(in) Print "[SYS] - User '"+leaver$+"' left the room ("+reason$+")" For o.user = Each user If o\stream <> in WriteLine o\stream, "_leave_user" WriteLine o\stream, leaver$ WriteLine o\stream, reason$ Else Delete o EndIf Next in_msg$ = ReadLine(in) End Select EndIf Wend Print "[SYS] - Server shutting down..." For a.user = Each user WriteLine a\stream, "_server_close" Next CloseTCPServer stream End und das ist der client dazu : Code: [AUSKLAPPEN] AppTitle "TCP-Chat | Client"
port = 21 Print "Nickname:" nick$ = Input("") Print "Server-IP:" ip$ = Input("") Print "Verbinde..." stream = OpenTCPStream(ip$, port) If stream <> 0 Print "Verbunden !" Print "Anmelden..." CountHostIPs("") own_ip$ = DottedIP$(HostIP(1)) Print "Eigene IP : "+own_ip$ Else Print "Server ist offline/existiert nicht!" Print "*Taste drücken*" WaitKey End EndIf WriteLine stream, "_new_user" WriteLine stream, own_ip$ WriteLine stream, nick$ WriteLine stream, 0 Print "Angemeldet!" Delay 500 Cls Locate 0, 0 While Not quit = 1 While ReadAvail(stream) in_msg$ = ReadLine(stream) If in_msg$ = "_new_user" name$ = ReadLine$(stream) Print "New User '"+name$+"' joined the room" ElseIf in_msg$ = "_in_msg" sender$ = ReadLine(stream) nachr$ = ReadLine(stream) Print "<"+sender$+"> : "+nachr$ ElseIf in_msg$ = "_leave_user" leaver$ = ReadLine$(stream) reason$ = ReadLine$(stream) Print "User '"+leaver$+"' left the room ("+reason$+")" ElseIf in_msg$ = "_server_close" Print "Server is closing now..." CloseTCPStream stream WaitKey End EndIf Wend If KeyHit(14) in$ = Input$(">") WriteLine stream, "_in_msg" DebugLog "Send : _in_msg" WriteLine stream, nick$ WriteLine stream, in$ DebugLog "Message : "+in$ If in$ = "/quit" quit = 1 EndIf EndIf Wend WriteLine stream, "_leave_user" WriteLine stream, nick$ WriteLine stream, "pressed ESC" CloseTCPStream stream End hoffe das hilft jetzt ein bissl ![]() |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
AcceptTcpStream![]() ![]() |
||
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 |
![]() |
DerKeks |
![]() Antworten mit Zitat ![]() |
---|---|---|
also das AcceptTCPStream vor die schleife?
was wäre dann wenn ein zweiter client dazu kommt? er würde doch nur das erste handle speichern was ankommt. mangels schleife würden die anderen doch dann garnicht mehr erkannt werden? oder ich versteht nicht wie dus meinst x) |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
So, weil mir grad deftig langweilig war, hab ich kurz n funktionierendes (ja, habs getestet) Beispiel geschrieben. Bitteschön:
Code: [AUSKLAPPEN] ; Definitionen
Const SERVERPORT = 8080 Const MAXCONN = 2 Const MSGT_CONNECT = $00 Const MSGT_ACC = $01 Const MSGT_SRVFULL = $02 Const MSGT_NEW = $03 Const MSGT_DISC = $04 Const MSGT_SRVCLOSE = $05 Const MSGT_CONNINFO = $10 Const MSGT_TEXT = $20 ; Programm Dim Printed$(17): Global PrintLine Graphics 400,300,0,2 SetBuffer BackBuffer() Global TIMER = CreateTimer(60) AppTitle "TCP Chat" Type TConnection Field ID Field Connected Field Stream Field Name$ End Type Local Connection.TConnection, SConnection.TConnection Local ConnectionCnt, ConnectionID Local Name$ Local IsServer Local LocalStream = CreateTCPServer( SERVERPORT ) Local LocalConnection.TConnection ; Programm ist host If LocalStream IsServer = True Connection = New TConnection Connection\ID = 0 Connection\Connected = False LocalConnection = Connection LocalConnection\Name = "Server" Print "Server gestartet." ; Programm ist client Else IsServer = False LocalStream = OpenTCPStream( "127.0.0.1", SERVERPORT ) Connection = New TConnection Connection\ID = 0 Connection\Connected = True Connection\Stream = LocalStream WriteByte LocalStream, MSGT_CONNECT Print "Verbinde..." EndIf ; Hauptschleife Local MsgT Local TcpIn While Not KeyDown(1) Cls If IsServer TcpIn = AcceptTCPStream( LocalStream ) ; Neue Verbindung herstellen If TcpIn ConnectionID = ConnectionID +1 Connection = New TConnection Connection\ID = ConnectionID Connection\Connected = True Connection\Stream = TcpIn EndIf EndIf ; Alle Verbindungen prüfen For Connection = Each TConnection If Connection\Stream If ReadAvail( Connection\Stream ) MsgT = ReadByte( Connection\Stream ) DebugLog MsgT ; Nachrichtentyp Prüfen Select MsgT ; Verbindungsanfrage Case MSGT_CONNECT ; Verbindung akzeptieren If ConnectionCnt < MAXCONN ConnectionCnt = ConnectionCnt +1 WriteByte Connection\Stream, MSGT_ACC WriteInt Connection\Stream, ConnectionID ; Server voll Else WriteByte Connection\Stream, MSGT_SRVFULL Delete Connection EndIf ; Verbindung aufgebaut Case MSGT_ACC ; Eigene ID auslesen ival = ReadInt( Connection\Stream ) ; Lokale "Connection"-Instanz LocalConnection = New TConnection LocalConnection\ID = ival LocalConnection\Name = "Client " +ival Print "Verbindung aufgebaut. Angemeldet als: " +LocalConnection\Name ; Vorstellen WriteByte Connection\Stream, MSGT_NEW WriteInt Connection\Stream, LocalConnection\ID WriteString Connection\Stream, LocalConnection\Name ; Verbindung kann nicht aufgebaut werden Case MSGT_SRVFULL Print "Verbindung kann nicht hergestellt werden," Print "der Server ist voll." ; Neuer Benutzer wird vorgestellt Case MSGT_NEW ival = ReadInt( Connection\Stream ) stval$ = ReadString( Connection\Stream ) Connection = GetConnectionById( ival ) Connection\Name = stval$ Print Connection\Name +" hat sich angemeldet." ; Der Server muss die Info an alle anderen Spieler weitergeben If IsServer = True For SConnection = Each TConnection If SConnection\Connected = True And SConnection <> Connection WriteByte SConnection\Stream, MSGT_NEW WriteInt SConnection\Stream, ival WriteString SConnection\Stream, stval$ EndIf Next ; ... und dem neuen alle Infos zu den anderen Spielern geben For SConnection = Each TConnection If SConnection <> Connection WriteByte Connection\Stream, MSGT_CONNINFO WriteInt Connection\Stream, SConnection\ID WriteString Connection\Stream, SConnection\Name EndIf Next EndIf ; Benutzer meldet sich ab Case MSGT_DISC ival = ReadInt( Connection\Stream ) Connection = GetConnectionById( ival ) Print Connection\Name +" hat sich abgemeldet." ; Der Server muss die Info an alle anderen Spieler weitergeben If IsServer = True For SConnection = Each TConnection If SConnection\Connected = True And SConnection <> Connection WriteByte SConnection\Stream, MSGT_DISC WriteInt SConnection\Stream, ival EndIf Next ConnectionCnt = ConnectionCnt -1 EndIf Delete Connection ; Server wurde beendet Case MSGT_SRVCLOSE Print "Server wurde beendet." ; Verbindungsinfos Case MSGT_CONNINFO ival = ReadInt( Connection\Stream ) stval$ = ReadString( Connection\Stream ) Connection = GetConnectionById( ival ) Connection\Name = stval Print "Erhalte Infos zu Teilnehmer " +ival +", Name: " +stval$ ; Textnachricht Case MSGT_TEXT ival = ReadInt( Connection\Stream ) stval$ = ReadLine( Connection\Stream ) Connection = GetConnectionById( ival ) Print Connection\Name +" sagt:" Print stval ; Der Server muss die Info an alle anderen Spieler weitergeben If IsServer = True For SConnection = Each TConnection If SConnection\Connected = True And SConnection <> Connection WriteByte SConnection\Stream, MSGT_TEXT WriteInt SConnection\Stream, ival WriteLine SConnection\Stream, stval EndIf Next EndIf End Select EndIf EndIf Next ; Einfacher Chat char = GetKey() If char = 8 txt$ = Left( txt$, Len( txt$ ) -1 ) ElseIf char = 13 ; Der Server sendet die Nachricht an alle If IsServer = True For SConnection = Each TConnection If SConnection\Connected = True WriteByte SConnection\Stream, MSGT_TEXT WriteInt SConnection\Stream, 0 WriteLine SConnection\Stream, txt$ EndIf Next ; Hosts nur an den Server Else WriteByte LocalStream, MSGT_TEXT WriteInt LocalStream, LocalConnection\ID WriteLine LocalStream, txt$ EndIf Print ">>> " +LocalConnection\Name +" sagt:" Print txt$ txt$ = "" ElseIf char > 31 txt$ = txt$ +Chr(char) EndIf Text 0,284, "> " +txt$ DrawPrint() Flip 0 WaitTimer( TIMER ) Wend ; Abmelden If IsServer For SConnection = Each TConnection If SConnection\Connected = True WriteByte SConnection\Stream, MSGT_SRVCLOSE EndIf Next Else WriteByte LocalStream, MSGT_DISC WriteInt LocalStream, LocalConnection\ID EndIf End Function Print( txt$ ) Printed( PrintLine ) = txt$ PrintLine = PrintLine +1 PrintLine = PrintLine Mod 17 End Function Function DrawPrint() For a = 0 To 16 Text 0,a *16, Printed( ( 17 + a +printline ) Mod 17 ) Next End Function Function GetConnectionById.TConnection( ID ) Local Conn.TConnection For Conn = Each TConnection If Conn\ID = ID Return Conn Next Conn = New TConnection Conn\ID = ID Return Conn End Function (Server und Client in einem Programm und zum Testen reicht es vollkommen, einfach zweimal auf Run zu klicken) Wie du siehst, reicht es, den Nachrichtentyp als Byte zu definieren. Mit der Sache wegen AcceptTcpStream: Die Funktion lieftert ein Streamhandle zurück, wenn eine neue TCP-Verbindung aufgebaut wurde. Logischerweise (um nachträglich immer noch alle Streams abfragen zu können) muss man dieses Handle in einem Type speichern. Um zu fragen, ob an einem Stream neue Daten ankamen, dient die Funktion ReadAvail(). Guck dich n wenig durch den Code, versuche ihn zu verstehen und mach dir selbst ein paar Gedanken, was ich wohl wieso auf diese Art gelöst habe. Der Code ist übrigens noch lange nicht ausgereift... da gehören nämlich noch Sicherheitsabfragen rein (was passiert zB wenn sich ein Client anmeldet, auch wenn er vom Server abgewiesen wurde, weil dieser voll ist) ein komplettes Timeout-Managment und vieles mehr. Achja: Und lass die Finger von der Print Funktion! Das ist nur n Workaround, weil ich zu spät gemerkt habe, dass es mit Print ja ziemlich hässlich wird, wenn man Nachrichten eingeben will. Es gäbe da also bestimmt noch schönere Lösungsmöglichkeiten. Und wenn noch Fragen offen sind, einfach fragen =) mfG |
||
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 |
![]() |
DerKeks |
![]() Antworten mit Zitat ![]() |
---|---|---|
danke dir...
der code scheint zu funzen :> werd ihn mir dann mal genauer anschauen um zu gucken was ich jetzt falsch gemacht habe danke ![]() |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group