BNetEx - Server + Multithreading?
Übersicht
BlitzMax, BlitzMax NG
Allgemein
|
Betreff: BNetEx - Server + Multithreading?
|
Mi, Jun 20, 2012 9:03
Antworten mit Zitat
|
Hallo Leute.
Ich habe ein kleines Problem.
Undzwar möchte ich einen kleinen Chat schreiben. Dazu benutze ich BnetEx und habe meinen Server auch nach dem dortigen TCPServer Example geschrieben.
Das Problem ist ja nur: Der Server läuft in einer Endlosschleife, damit sich die Clients verbinden könnten.
Ich möchte aber über den Server eine MaxGui Schicht drüber legen, damit ich die Ausgaben prüfen kann.
Das funktioniert mit einer Endlosschleife natürlich nicht.
Jetzt wollte ich die Listen-Funktion des Servers einfach in einen extra Thread auslagern.
Aber dann hört das Programm einfach ohne jedes Kommentar auf. Auch wenn ich eine Try/Catch Anweisung darumlege wird kein Fehler abgefangen, also scheint keiner aufzutreten.
Mein Server sieht so aus:
BlitzMax: [AUSKLAPPEN] [EINKLAPPEN] Type TServer Field _ttcpsServerStream:TTCPStream Field _tlConnectedClients:TList Field _ttcpsClientStream:TTCPStream Field _tmClientStreamByNickname:TMap Field _tmNicknameByClientStream:TMap Method ServerStream:TTCPStream() Return _ttcpsServerStream End Method Method SetServerStream(pttcpsServerStream:TTCPStream) _ttcpsServerStream = pttcpsServerStream End Method Method ConnectedClients:TList() Return _tlConnectedClients End Method Method SetConnectedClients(ptlConnectedClients:TList) _tlConnectedClients = ptlConnectedClients End Method Method ClientStream:TTCPStream() Return _ttcpsClientStream End Method Method SetClientStream(pttcpsClientStream:TTCPStream) _ttcpsClientStream = pttcpsClientStream End Method Method ClientStreamByNickname:TMap() Return _tmClientStreamByNickname End Method Method __SetClientStreamByNickname(ptmClientStreamByNickname:TMap) _tmClientStreamByNickname = ptmClientStreamByNickname End Method Method AddNickname(psNickname:String, pttcpsClientStream:TTCPStream) End Method Method NicknameByClientStream:TMap() Return _tmNicknameByClientStream End Method Method __SetNicknameByClientStream(ptmNicknameByClientStream:TMap) _tmNicknameByClientStream = ptmNicknameByClientStream End Method Function Create:TServer(piPort:Int) Local serv:TServer = New TServer serv.SetConnectedClients(New TList) serv.SetServerStream(New TTCPStream) serv.Start(piPort) Return serv End Function Method Start(piPort:Int) If(Not ServerStream().Init()) Then Throw("Socket could not be created.") If(Not ServerStream().SetLocalPort(piPort)) Then Throw("Couldn't set local port to " + piPort + ".") If(Not ServerStream().Listen()) Then Throw("Can't set socket state to listen.") Print("******************************") Print("Server is ready to be used") End Method Function StartServer(ptseServer:TServer) ptseServer.Listen() End Function Function StartListen:Object(ptseServer:Object) TServer(ptseServer).Listen() End Function Method Listen() Print("Server starting to listen") Print("******************************") Print("") Repeat SetClientStream(ServerStream().Accept()) If(ClientStream() <> Null) Then Print("New Client:~n" + .. " - IP:" + TNetwork.StringIP(ClientStream().GetLocalIP()) + "~n" + .. " - Port:" + ClientStream().GetLocalPort() + "~n") ConnectedClients().AddLast(ClientStream()) EndIf For Local str:TTCPStream = EachIn ConnectedClients() SetClientStream(str) If(ClientStream().GetState() <> 1) Then Print("Client disconnected:~n" + .. " - IP:" + TNetwork.StringIP(ClientStream().GetLocalIP()) + "~n" + .. " - Port:" + ClientStream().GetLocalPort() + "~n") ClientStream().Close() ConnectedClients().Remove(ClientStream()) Continue EndIf If(ClientStream().RecvAvail() <> (-1)) Then While(ClientStream().RecvMsg()) Wend If(ClientStream().Size() > 0) Then Print("Message from client:~n" + .. " - IP:" + TNetwork.StringIP(ClientStream().GetLocalIP()) + "~n" + .. " - Port:" + ClientStream().GetLocalPort() + "~n") While(Not ClientStream().Eof()) Print(">" + ClientStream().ReadLine() + "~n") Wend ClientStream().WriteLine("Okay") While(ClientStream().SendMsg()) Wend EndIf EndIf Next Forever End Method Method SendMessageToAll(psNickName:String, psMessage:String) End Method End Type
Global myServer:TServer = TServer.Create(1300)
TServer.StartServer(myServer)
Wenn ich das mit Multithreads mache, dann ändere ich nur diese Funktion folgendermaßen:
BlitzMax: [AUSKLAPPEN] [EINKLAPPEN] Function StartServer(ptseServer:TServer) Local thread:TThread = TThread.Create(StartListen, ptseServer) End Function
Das Problem: Ich habe mit Multithreads dann noch die Ausgabe:
Zitat:******************************
Server is ready to be used
Server starting to listen
******************************
Aber direkt nach der Ausgabe beendet sich das Programm. Er startet also den neuen Thread und ruft die Listen-Methode auf, aber läuft scheinbar nicht in die Schleife.
Ohne Multithreading funktioniert das ganze.
Kann mir bitte jemand weiterhelfen und mir sagen, was ich falsch mache?
Lg, M0rgenstern
|
|
|
Moderator
|
Mi, Jun 20, 2012 9:14
Antworten mit Zitat
|
Wo liegt denn das Problem darin in MaxGUi im Hauptast immer wieder deine listen-funtion aufzurufen und damit auf das repeat forever zu verzichten?
|
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI
Stolzer Gewinner des BAC#48, #52 & #92
|
|
|
Mi, Jun 20, 2012 9:20
Antworten mit Zitat
|
nen chat ist ja nun nicht zeitkritisch, also bei maxgui einfach
nen Timer dafür anlegen und funktion bei EVENT_TIMERTICK
wie BR beschrieb aufrufen.
Grüße
|
blucode - webdesign - Ressource - NetzwerkSim
BlitzBasic 2D - BlitzMax - MaxGUI - Monkey - BlitzPlus
|
|
|
Mi, Jun 20, 2012 13:44
Antworten mit Zitat
|
Hey.
Vielen Dank euch beiden. So funktioniert das.
@BladeRunner: Gegen die Vorgehensweise spricht natürlich nichts, außer dass ich beschränkt gedacht habe.
Lg, M0rgenstern
|
|
Übersicht
BlitzMax, BlitzMax NG
Allgemein
Powered by phpBB © 2001 - 2006, phpBB Group