| 
				
					|  | Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
 |  
 
	
		| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |  
		| Autor | Nachricht |  
		| stevie1401 
 
 
 Anmeldungsdatum: 04.07.2006
 Beiträge: 133
 
 
 | 
			
				|  Verfasst am: 06.12.2012, 09:41    Titel: Socket Server ohne Threads |   |  
				| 
 |  
				| Ich suche noch immer händeringend einen Socket Server, der ohne Threads arbeitet. TSNE kann ich leider nicht nutzen, da ich mit global shared Variablen arbeiten muss und ich die Verwaltung dieser Variablen mit TSNE einfach nicht gebacken bekomme.
 
 Nun habe ich im englischen Forum diesen Code gefunden:
 
  	  | Code: |  	  | #include "network.bi"
 #include "fbgfx.bi"
 
 #DEFINE SERVER_PORT 27015
 #DEFINE CLIENT_IP "127.0.0.1"
 
 '--- SERVER ---
 
 dim as SOCKET socketId
 dim as sockaddr_in clientAddr
 dim as sockaddr_in serverAddr
 dim as integer serverAddrSize = sizeof(serverAddr)
 dim as integer clientAddrSize = sizeof(clientAddr)
 dim as integer iResult, quit, sendData, sendCount
 dim as string key
 
 dim as net_data netDataIn
 dim as net_data netDataOut
 
 dim as fd_set readfds, readfds0
 dim as fd_set writefds, writefds0
 dim as timeval timeout
 
 iResult = init_socket_API()
 if (iResult <> 0) then
 print "Winsock init: Error"
 sleep
 end
 end if
 
 socketId = socket_(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
 if (socketId < 0) then
 print "Socket: Error"
 close_socket_API()
 end
 end if
 
 serverAddr.sin_family = AF_INET
 serverAddr.sin_port = htons(SERVER_PORT)
 serverAddr.sin_addr.s_addr = htonl(INADDR_ANY)
 
 iResult = bind(socketId, cptr(sockaddr ptr, @serverAddr), serverAddrSize)
 if (iResult < 0) then
 print "Bind: Error"
 close_socket_API()
 sleep
 end
 end if
 
 clientAddr.sin_family = AF_INET
 clientAddr.sin_port = htons(SERVER_PORT)
 clientAddr.sin_addr.s_addr = inet_addr(CLIENT_IP)
 
 FD_ZERO(@readfds0)
 FD_ZERO(@writefds0)
 FD_SET_(socketId, @readfds0)
 FD_SET_(SocketId, @writefds0)
 
 print "q = quit"
 print "s = send"
 
 while (quit = 0)
 
 quit = 0: sendData = 0
 key = lcase(inkey())
 if (key = "q") then quit = 1
 if (key = "s") then sendData = 1
 
 'Keep a backup because SelectSocket will change the data
 readfds = readfds0
 writefds = writefds0
 timeout = type(0, 0)
 
 iResult = selectSocket(FD_SETSIZE, @readfds, @writefds, NULL, @timeout)
 if (iResult = 0) then
 print "SelectSocket: Timeout"
 elseif (iResult < 0) then
 print "SelectSocket: Error"
 else
 'print "SelectSocket: Sockets ready: "; iResult
 end if
 
 if(sendData = 1) then
 netDataOut.seqNr = sendCount
 netDataOut.text = "Server says: No!"
 if(FD_ISSET(socketId, @writefds)) then
 print "Send: Trying..."
 iResult = sendto(socketId, cptr(ubyte ptr, @netDataOut), _
 sizeof(net_data), 0, cptr(sockaddr ptr, @clientAddr), clientAddrSize)
 if (iResult < 0) then
 print "Send: Error"
 closeSocket(socketId)
 close_socket_API()
 sleep
 end
 else
 print "Bytes send:"; iResult;
 print " to: "; inet_addr_rev(clientAddr.sin_addr)
 end if
 end if
 sendCount += 1
 end if
 
 if(FD_ISSET(socketId, @readfds)) then
 print "Receive: Trying..."
 iResult = recvfrom(socketId, cptr(ubyte ptr, @netDataIn), _
 sizeof(net_data), 0, cptr(sockaddr ptr, @clientAddr), @clientAddrSize)
 if (iResult > 0) then
 print "Bytes received:"; iResult;
 print " from: "; inet_addr_rev(clientAddr.sin_addr)
 print "SeqNr: "; netDataIn.seqNr;
 print " text: "; netDataIn.text
 elseif (iResult = 0) then
 print "Receive: Connection closed"
 closesocket(socketId)
 close_socket_API()
 sleep
 end
 else
 print "Receive: Error"
 closesocket(socketId)
 close_socket_API()
 sleep
 end
 end if
 end if
 
 sleep 1, 1
 
 wend
 
 iResult = closesocket(socketId)
 if (iResult < 0) then
 print "CloseSocket: Error"
 end if
 close_socket_API()
 
 print "End."
 sleep
 
 | 
 
 Arbeitet dieser Code ohne Threads? So ganz verstehe ich den Code leider nicht. Für jede Erklärungshilfe wäre ich dankbar.
 Ansonsten wäre ich auch dankbar für einen Beispielcode, der mit WSAAsyncselect und/oder WSAEventselect arbeiten würde.
 Vielen Dank
 Stevie
 |  |  
		| Nach oben |  |  
		|  |  
		| darkinsanity aka sts
 
  
 Anmeldungsdatum: 01.11.2006
 Beiträge: 456
 
 
 | 
			
				|  Verfasst am: 06.12.2012, 20:19    Titel: |   |  
				| 
 |  
				| Ja, er arbeitet ohne Threads, da ja nirgendwo einer erstellt wird. Allerdings ist das direkte Benutzen der Socket-APIs meiner Meinung nach eine ziemlich hässliche Sache. Du erstellst hier einen UDP-Socket und wartest bis er bereit ist. Wenn du "s" drückst, sendet er etwas (in diesem Falle wohl an 127.0.0.1), wenn er erkennt, dass es Daten gibt, die er abholen kann, empfängt er sie. Danach wartet er kurz per sleep und fragt dann wieder (per select) ob der Socket bereit ist.
 UDP ist allerdings Verbindungslos, daher bin ich mir nicht ganz sicher ob dieses Protokoll auch wirklich benutzen willst.
 
  	  | stevie1401 hat Folgendes geschrieben: |  	  | Ich suche noch immer händeringend einen Socket Server, der ohne Threads arbeitet. TSNE kann ich leider nicht nutzen, da ich mit global shared Variablen arbeiten muss und ich die Verwaltung dieser Variablen mit TSNE einfach nicht gebacken bekomme.
 | 
 Was genau ist denn dein Problem? Im Prinzip musst du nur dafür sorgen dass deine Variablen entsprechend initialisiert sind und du sie vor gleichzeitigem Zugriff schützt (z.B. per Mutex). Die API von TSNE ist deutlich schöner als das direkte Socket-Interface und du kannst deutlich weniger falsch machen.
 _________________
 Traue keinem Computer, den du nicht aus dem Fenster werfen kannst -- Steve Wozniak
 |  |  
		| Nach oben |  |  
		|  |  
		| stevie1401 
 
 
 Anmeldungsdatum: 04.07.2006
 Beiträge: 133
 
 
 | 
			
				|  Verfasst am: 07.12.2012, 15:04    Titel: |   |  
				| 
 |  
				| Erst einmal vielen Dank für deine Antwort. Bei meinem Programm handelt es sich um einen Doppelkopf-Server.
 Allein schon die Tatsache, dass der Server allen Spielern am Tisch die Karten auf dem Tisch anzeigen soll,
 wenn jemand eine Karte geschmissen hat,macht TSNE sinnlos, denn er muss demuxen oder muxen was das Zeug hält.
 Da kann ich gleich einen threadlosen Server bauen. Ich habe es mehrfach mit TSNE probiert, aber es funktioniert einfach nicht und ist eine irre Arbeit.
 Von einfach kann da keine Rede sein, leider.
 Zur Zeit arbeite ich mit WSAAsyncselect, was teilweise recht gut funktioniert, aber natürlich auch Nachteile hat. Zum Beispiel, dass ich ein Fenster brauche.
 Deshalb fällt leider auch ein vServer aus und ich muss den Server über einen meiner Rechner laufen lassen.
 Deshalb wäre ich über einen Beispielcode mit WSAeventselect sehr dankbar.
 |  |  
		| Nach oben |  |  
		|  |  
		| ThePuppetMaster 
 
  
 Anmeldungsdatum: 18.02.2007
 Beiträge: 1839
 Wohnort: [JN58JR]
 
 | 
			
				|  Verfasst am: 07.12.2012, 15:44    Titel: |   |  
				| 
 |  
				| Naja.... @ stevie ... eigentlich ist das Problem eher, das du den server komplett umschreiben müsstest. Du weist ja, da sind viele Strukturelle Probleme vorhanden. an TSNE liegt das in dem Falle nicht. 
 Und, wild muxen muss man da auch nicht, wenn der source entsprechend geschrieben ist.
 Andernfalls natürlich schon. Aber, das ist ja beim umbauen von einem zum anderem immer recht problematisch.
 
 
 MfG
 TPM
 _________________
 [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
 |  |  
		| Nach oben |  |  
		|  |  
		| stevie1401 
 
 
 Anmeldungsdatum: 04.07.2006
 Beiträge: 133
 
 
 | 
			
				|  Verfasst am: 07.12.2012, 17:29    Titel: |   |  
				| 
 |  
				| Die "strukturellen Probleme" sind die shared Variablen, wenn ich TSNE verwenden will. Aber nur dann. Ich weiß beim besten Willen nicht wie ich die NICHT benutzen sollte, denn irgendwie müssen die Spielernamen, Tische etc. gehandelt werden.
 Dies kann m.E. nur global gemacht werden. Dies wäre auch beim schreiben in eine Datenbank nicht anders. Auch dort würde es sofort E/A Fehler geben,
 sobald mehrere Clients darin lesen wollen.
 Ich wüßte also nicht einmal im Ansatz wie ich einen Server schreiben kann, der Daten on the fly bearbeitet und verwalten muß, damit er mit TSNE funktioniert.
 Aber vielleicht kannst du mir ja mal einen Tip geben.
 Vielen Dank.
 |  |  
		| Nach oben |  |  
		|  |  
		| ThePuppetMaster 
 
  
 Anmeldungsdatum: 18.02.2007
 Beiträge: 1839
 Wohnort: [JN58JR]
 
 | 
			
				|  Verfasst am: 07.12.2012, 17:34    Titel: |   |  
				| 
 |  
				| Prinzipiel kannst du dich an dem hier orientieren. Ist zwar ein HTTP Server, nutzt aber die selben mechanissmen. 
 http://www.freebasic-portal.de/porticula/test-serverbas-740.html
 
 fast ganz unten findest du ein
 
 
  	  | Code: |  	  | Case "/status"                                  'Der CLient will einen Status haben T += "<html>"                             'Es wir deien HTML-Seite erzeugt
 T += " <head>"
 T += "  <title>Test-Server</title>"         'Mit eine Titel
 T += " </head>"
 T += " <body>"
 T += "  <p>= Mein Status =</p>"             'Und einem sichtbarem Text
 MutexLock(ClientMutex)                      'Wir müssen das MUTEX sperren, weil wir auf daten im Array zugreifen
 T += "  <p>Ich habe / hatte maximal " & ClientC & " Verbindungen gleichzeitig</p>"
 T += "  <p>Deine IP-Adresse: " & ClientD(CIndex).V_IPA & "</p>"
 T += "  <p><a href=""block"">Blockiere meine IP-Adresse</a></p>"
 MutexUnLock(ClientMutex)                    'Danach können wir die Sperre wieder aufheben
 T += " </body>"
 T += "</html>"                                'Es wir deien HTML-Seite erzeugt
 
 | 
 
 Dort ist zu erkennen, das beim zugriff auf globale variablen eine mutexsterre erfolgt.
 
 
 Aber, wie schon geschrieben, empfehle ich dir hier dringend, das gesammtkonzept neu zu gestalten. Die vorgehensweise und der code-aufbau ist schon recht verworren, um das ganze effizient zu halten.
 
 
 MfG
 TPM
 _________________
 [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
 |  |  
		| Nach oben |  |  
		|  |  
		| stevie1401 
 
 
 Anmeldungsdatum: 04.07.2006
 Beiträge: 133
 
 
 | 
			
				|  Verfasst am: 07.12.2012, 18:03    Titel: |   |  
				| 
 |  
				| Vielen Dank! Kann ich in das
 MutexLock(ClientMutex)
 
 MutexUnLock(ClientMutex)
 jetzt die Nachricht von den Clients reinpacken und in einer sub bearbeiten?
 
 Wie oben schon geschrieben, ich wüßte nicht einmal im Ansatz, wie ich das ohne shared Variablen machen könnte.
 Und - das möchte ich auch erwähnen - das Konzept ist eigentlich sehr gut durchdacht.
 Es mag als Nicht-GFA-Progger etwas verwirrend sein, es ist tatsächlich aber sehr logisch aufgebaut und GFA-Progger können den Code sehr gut und sehr leicht nachvollziehen.
 Es funktioniert ja auch als Netzwerkserver mit WSAAsyncselect, aber genau das möchte ich ja am liebsten umgehen.
 
 Noch etwas anderes:
 Wenn bei jeder Clientnachricht ein
 
 MutexLock(ClientMutex)
 GehInSubBearbeiteDaten
 MutexUnLock(ClientMutex)
 
 erfolgen muss, welchen Sinn machen dann die Threads noch? Ich stelle sie ja bei jedem Durchgang aus oder verstehe ich da was falsch?
 |  |  
		| Nach oben |  |  
		|  |  
		| ThePuppetMaster 
 
  
 Anmeldungsdatum: 18.02.2007
 Beiträge: 1839
 Wohnort: [JN58JR]
 
 | 
			
				|  Verfasst am: 08.12.2012, 00:55    Titel: |   |  
				| 
 |  
				| Hatest du mal die Links von mir durchgelesen, die ich dir in der PM geschickt hatte? .. bezüglich Threads udn Mutexe? .. dort ist eigentlich beschrieben, wie man mit soetwas umgeht, und wo die probleme dabei sind. 
 Das MutexLock() / Unlock solltest du nur um die elemente legen, die shared sind.
 
 
 beispiel:
 
 
  	  | Code: |  	  | dim shared bla as uinteger
 
 sub foo()
 dim abc1 as uinteger
 dim abc2 as uinteger
 dim abc3 as uinteger
 mutexlock(...) 'bla ist eine shared. daher muss der zugriff via mutex gesperrt werden
 abc1 = bla
 mutexUnlock(...) 'danach kann das wieder freigegeben werden
 abc2 = abc1 * 2
 mutexlock(...) 'hier folgt wieder ein zugriff auf die shared. daher wieder locken
 abc3 = abc2 + bla
 mutexUnlock(...)
 end sub
 
 foo()
 end 0
 
 | 
 
 wie zu erkennen, wird die sperre nur dann benötigt, wenn ein zugriff auf die shared von nöten ist. andernfalls nicht.
 
 nochmal, hier kannst du dich bezüglich dieser themen informieren:
 threading: http://www.freebasic-portal.de/tutorials/threading-56.html ... probleme und handling von threads incl mutex-schutz
 
 mutex: http://www.freebasic-portal.de/tutorials/mutexe-54.html ... was mutexe machen.
 
 
 MfG
 TPM
 _________________
 [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
 |  |  
		| Nach oben |  |  
		|  |  
		| stevie1401 
 
 
 Anmeldungsdatum: 04.07.2006
 Beiträge: 133
 
 
 | 
			
				|  Verfasst am: 08.12.2012, 08:07    Titel: |   |  
				| 
 |  
				| Du ahnst gar nicht wieviele Stunden und Tage ich mich schon mit TSNE beschäftigt habe. Natürlich habe ich schon alle deine Beispiele mehrfach durchgekaut.
 Genau deshalb bin ich ja zu dem Ergebnis gekommen, dass TSNE nicht anwendbar ist, zumindest nicht für mich.
 Ich verstehe den Code nicht und er ist für mich nicht nachvollziehbar.
 Ich weiss nicht wann ich mutexlock und mutexunlock anwenden kann oder wie.
 Die einzige Chance für mich würde ich sehen, wenn ich mutexlock machen könnte, dann die Nachrichten vom Client verarbeiten könnte und dann wieder mutexunlock machen könnte.
 Ich habe nun mehrfach gefragt ob bzw. wie das gehen könnte, habe diesbezüglich aber keine Antwort erhalten.
 Probiert habe ich vieles, funktioniert hat nichts.
 Das Problem ist doch folgendes:
 Die Nachricht vom Client kommt rein.
 Nun müssen Serverseitig zwangsläufug ganz viele Routinen durchlaufen werden, die dim shared Variablen beinhalten, um zu gucken, welcher Spieler an welchem Tisch welche Karte geworfen hat.
 Der Server müßte also nach Erhalt der Clientnachricht ein mutexlock machen, die Daten verarbeiten und dann wieder ein mutexunlock.
 Dies funktioniert aber überhaupt nicht, denn der Server hängt sich immer auf.
 Also frage ich letztmalig (dann gebe ich es echt auf hier):
 Wie kann ich die Nachricht vom Client KOMPLETT mutexgesperrt verarbeiten?
 
 Inzwischen habe ich für mich ja eigentlich ja auch schon TSNE abgehakt und würde mich über ein Beispiel mit Freebasic  mit WSA Asyncselect oder WSAeventselect freuen.
 |  |  
		| Nach oben |  |  
		|  |  
		| nemored 
 
  
 Anmeldungsdatum: 22.02.2007
 Beiträge: 4711
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 08.12.2012, 12:18    Titel: |   |  
				| 
 |  
				| Wenn sich der Server aufhängt, lockst du vermutlich falsch - zwei MUTEXLOCK ohne MUTEXUNLOCK oder etwas in der Art. 
 Die Spieler werfen doch nicht gleichzeitig ihre Karten? Von der Theorie her würde ich das so angehen: Der Server teilt Spieler X mit, dass er am Zug ist und wartet auf Rückmeldung. Sobald er die bekommt, schickt er an alle Spieler den aktuellen Spielstand und dann dem nächsten Spieler die Information, dass er an der Reihe ist. Nur die ausgetauschten Nachrichten muss tatsächlich gekapselt werden; die Nachricht kann dann auch (mutexgeschützt) in eine lokale Variable übertragen werden, auf die du (ohne MUTEXLOCK) problemlos weiter zugreifen kannst.
 
 ThePuppetMaster hat ein paar Sachen als Tutorial ins Portal gestellt; ansonsten kannst du auch mal in mein Buch schauen, da gehe ich auch knapp auf die Thematik ein (interessant wohl vor allem Kapitel 8 ).
 _________________
 Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
 
 Zuletzt bearbeitet von nemored am 08.12.2012, 12:27, insgesamt 2-mal bearbeitet
 |  |  
		| Nach oben |  |  
		|  |  
		| ThePuppetMaster 
 
  
 Anmeldungsdatum: 18.02.2007
 Beiträge: 1839
 Wohnort: [JN58JR]
 
 | 
			
				|  Verfasst am: 08.12.2012, 12:27    Titel: |   |  
				| 
 |  
				| @nemored 
 idee ist nicht schlecht, aber nicht schön machbar, denn es gibt ja noch n haufen anderer Dinge, die asynchron gehandelt werden sollten.
 
 z.B. Das Senden von Nachrichten (Chat), neue Spieler, spieler die den raum verlassen, spielen die einen raum wechseln, spieler die den server verlassen, usw.
 
 wenn jemand am ziehen ist, udn derjenige hat sagen wir mal max. 15sec dafür, dann müssen all diese anderen nachrichten min. 15sec warten. will also jemand einen anderen raum betreten und klickt auf "join", dann muss er "kurioser weise" erstmal (im schelchtestem falle) 15sec warten, bis er eine rückmeldung vom server für diese operation erhält.
 
 Daher sollte ja sowas (vorallem bei server) asynchron gemacht werden.
 
 Wie man das aber macht, bleibt natürlich jedem selbst überlassen.
 
 @stevie1401
 
 prinzipiel kannst du auch so vorgehen. Wenn du nicht expliziet die optimierung verwenden willst, das der zugriff auf zu schützende resourcen (shared vars) effektiv wird, dann kannst du regulär ganz normal die verarbeitungsroutine für die daten per mutexlock() und Unlock() einklammern.
 
 so wie von dir beschrieben.
 
  	  | Code: |  	  | MutexLock(ClientMutex) GehInSubBearbeiteDaten
 MutexUnLock(ClientMutex)
 
 | 
 
 das macht zwar den sinn hinter "asynchron" kaput, aber funktionieren tut es.
 
 Wichtig ist nur, das du in den locked bereichen keine "wartenden" dinge tust. Das kann dann zu probleme führen, wie ein hängen, Auch rekrusive aufrufe führen dazu (welche schwer zu lokalisieren sind).
 
 die "verarbeiten" routine sollte so schnell wie möglich die daten verarbeiten. Ohne wartezeit! dann funzt es regulär problemlos.
 
 
 MfG
 TPM
 _________________
 [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
 |  |  
		| Nach oben |  |  
		|  |  
		| nemored 
 
  
 Anmeldungsdatum: 22.02.2007
 Beiträge: 4711
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 08.12.2012, 12:40    Titel: |   |  
				| 
 |  
				| Das mit der asynchronen Verarbeitung ist schon richtig; das ist aber dann doch nur ein begrenzter Befehlsbereich, der da abgearbeitet werden muss. So viele verschiedene Einzelnachrichten, auf die ich da reagieren muss, kommen da gar nicht zusammen (zumal TSNE ja für das joinen gleich noch eine extra Prozedur aufruft, wenn ich mich nicht irre). Kommt natürlich auch auf das Spiel an - bei einem Kartenspiel macht es in der Regel nicht viel Sinn, während des Spiels beizutreten, es sei denn du bist rausgeflogen und musst dich wiederverbinden. 
 Was ich letztendlich damit sagen will: Grundlage für einen reibungslosen Ablauf ist ein gutes Netzwerkprotokoll.
  _________________
 Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
 |  |  
		| Nach oben |  |  
		|  |  
		| ThePuppetMaster 
 
  
 Anmeldungsdatum: 18.02.2007
 Beiträge: 1839
 Wohnort: [JN58JR]
 
 | 
			
				|  Verfasst am: 08.12.2012, 12:43    Titel: |   |  
				| 
 |  
				| jo. ein gutes protokoll ist natürlich ein wichtiger faktor. 
 bezüglich join und tsne.
 naja... tsne erzeugt pro verbindung zwischen server und client einen eigenen thread.
 10 verbindungen = 10 threads.
 
 Worauf ich beim "join" hinaus wollte ist eher in richtung "bewegung auf dem server".
 Wenn man die verbindugn zum server etabliert hat, erhält man z.B. eine liste mit möglichen räumen, welche man betreten kann. udn das gäbe bei "wartebefehle" in der datenverarbeitungs-routine probleme bezüglich dem timing.
 
 
 MfG
 TPM
 _________________
 [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
 |  |  
		| Nach oben |  |  
		|  |  
		| stevie1401 
 
 
 Anmeldungsdatum: 04.07.2006
 Beiträge: 133
 
 
 | 
			
				|  Verfasst am: 08.12.2012, 12:55    Titel: |   |  
				| 
 |  
				| Erst mal vielen Dank für eure Mühen   Und genau, Puppetmaster, so einfach ist das alles leider nicht.
 Anhand der ClientNachricht agiert der Server.
 Wirft ein Spieler eine Karte, so teilt der Server dies nur den Spielern an seinem Tisch mit.
 Verlässt ein Spieler einen Tisch, so teilt er dies allen Spielern mit, da diese wissen müssen, dass ein Platz an einem Tisch freigeworden ist.
 Das Chatten ist noch komplizierter: Man kann am Tisch chatten, in der Lobby (ein anderer Raum), man kann "flüstern", also nur an eine gezielte Person etwas schreiben oder man kann an alle Spieler etwas schreiben.
 Es gibt also viele Sendeoptionen - und genau da ist, glaube ich, der Hund begraben.
 Per WSAAsyncselect klappts ja (auch wenn der Server manchmal einen Spieler einfach rausschmeisst, aber der kann sich einfach wieder anmelden und weiterspielen),
 mit dem
 MutexLock(ClientMutex)
 GehInSubBearbeiteDaten
 MutexUnLock(ClientMutex)
 klappt es leider nicht.
 |  |  
		| Nach oben |  |  
		|  |  
		| ThePuppetMaster 
 
  
 Anmeldungsdatum: 18.02.2007
 Beiträge: 1839
 Wohnort: [JN58JR]
 
 | 
			
				|  Verfasst am: 08.12.2012, 12:59    Titel: |   |  
				| 
 |  
				| das der server einen raus schmeist, kann z.B. einfach daran liegen, weil "wartende routinen" in der verarbeitung vorhanden sind. dadurch kommt es zu "lags" wärend der kommunikation in folge davon zu einem timeout, wodurch der server / client die verbindung trennt. 
 wenn du mir mal das kommunikations-protokoll zukommen lannen kannst, schaue ich mal, ob ich das per tsne realisiert bekomme.
 
 
 MfG
 TPM
 _________________
 [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
 |  |  
		| Nach oben |  |  
		|  |  
		| nemored 
 
  
 Anmeldungsdatum: 22.02.2007
 Beiträge: 4711
 Wohnort: ~/
 
 | 
			
				|  Verfasst am: 08.12.2012, 13:04    Titel: |   |  
				| 
 |  
				| Der Vorteil beim Chat ist, dass die Abarbeitung nicht übermäßig zeitkritisch ist. Bei einem Spiel wäre es schon ärgerlich, wenn derjenige, der als erstes reagiert, dann erst als letzter abgearbeitet wird. Wenn meine Chat-Nachricht eine viertel Sekunde zu spät abgearbeitet wird, ist mir (persönlich) das relativ egal. 
 Wie gesagt, einfacher ist das System
 
  	  | Code: |  	  | DIM AS nachrichtentyp meineLokaleNachricht MUTEXLOCK meinMutex
 meineLokaleNachricht = aktuelleGlobaleNachrichtenvariable
 MUTEXUNLOCK meinMutex
 SELECT CASE meineLokaleNachricht
 ' ...
 END SELECT
 | 
 
 Stark vereinfacht, aber so hast du so wenig gelockt wie möglich.
 _________________
 Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
 |  |  
		| Nach oben |  |  
		|  |  
		| RWK 
 
 
 Anmeldungsdatum: 04.07.2011
 Beiträge: 44
 
 
 | 
			
				|  Verfasst am: 08.12.2012, 15:11    Titel: |   |  
				| 
 |  
				| Stevie, 
 ich glaube nicht das das so schwer wäre mit TSNE.
 
 Ich für meinen Teil benutze bei meinem Laufzeiterfassungsprogramm das TSNEPlay...und das wäre sicherlich auch für Dich geeignet.
 
 Und bei Zieleinläufen treten dort sicherlich mehr Aktionen am Server auf als bei ein paar Doppelkopfrunden würde ich jetzt mal frech behaupten.
 
 Bei mir sind des..
 1 x Teilnehmererfassung die die sich anmeldenden Läufer eingibt (auch während andere Läufe laufen)
 2 x Zeitnehmer die ein Signal senden wenn jemand über die Ziellinie läuft
 1 x Platzierungsnehmer der gleichzeitig die Startnummern gemäß der Einlauffolge erfasst.
 1 x Moderator der ständig Startnummer abfragt, damit er Name, Verein, Altersklasse etc vom Server bekommt. und er bekommt immer die Einlaufzeiten und dann den Einläufer übermittelt damit er ein vorläufiges Ergebnis hat.
 1 x ein Auswerter, der die Zieleinläufe kontrolliert und ein endgültiges Ergebnis erstellt.
 
 und das ganze wird auch gleichzeitig noch in einer SQLite Datenbank weggeschrieben.
 
 und noch dazu ist das bei mir alles andere als sauber gecodet, weil mir einfach die Zeit fehlt das ordentlich zu bauen...
 trotzdem...
 das alles wickelt der Server ab und hat noch Langeweile. So wird es auch in deinem Fall sein, wenn nicht 1000 Leute gleichzeitig spielen.
 
 Der Server macht nix anderes als :
 
 
  	  | Code: |  	  | Sub TSNEPlay_Message(ByVal V_FromPlayerID As UInteger, ByVal V_ToPlayerID As UInteger, ByVal V_Message As String, ByVal V_MessageType As TSNEPlay_MessageType_Enum) Dim As String text = "[NACH]   Von PlayerID:" & V_FromPlayerID & "   Fuer PlayerID:" & V_ToPlayerID & "   Type:"
 text = text & "   Nachricht:>" & V_Message & "<"
 Console (text)
 Select Case V_MessageType
 Case TSNEPlay_MSGType_Regular
 checkMessage(V_FromPlayerID, V_Message)
 Case TSNEPlay_MSGType_Private
 Case TSNEPlay_MSGType_Notice
 AddMessage (V_FromPlayerID, V_Message)
 Case TSNEPlay_MSGType_Hightlighted
 Case Else
 End Select
 
 End Sub
 | 
 
 
  	  | Code: |  	  | Sub checkMessage(ByVal User As UInteger, ByVal Message As String) Dim As String xText, a, b
 Dim As Integer x,y
 
 Select Case (Left(Message,8))
 Case "GogoLauf"
 StartLauf
 Case "Get_Time"
 xText = "Set_Time:" & aktTime
 xText += ";" & aktLauf.lStatus
 xText += ";" & aktLauf.lName
 xText += ";" & aktLauf.lStarter
 xText += ";" & aktLauf.lZusatz1
 xText += ";" & aktLauf.lZusatz2
 TSNEPlay_SendMSG(User, xText )
 Case "Get_Teil"
 xText = Mid(Message,10)
 Do
 If xtext = teilnehmerdb(x,0) Then
 xText = "Get_Teil:" & teilnehmerDB(x,2) & " " & teilnehmerDB(x,1) & Chr(13) & Chr(10) & TeilnehmerDB(x,3) & " -- " & teilnehmerDB(x,9)
 Exit Do
 End If
 x = x + 1
 Loop Until teilnehmerdb(x,0) = ""
 If Left(xText,1) <> "G" Then
 xText = "Get_Teil:" & "Nummer nicht gefunden!"
 End If
 TSNEPlay_SendMSG(User, xText)
 Case "Set_Teil"
 xText = Mid(Message,10)
 If xText = "ALLE" Then
 SendeAlleTeilnehmer (user)
 Exit Sub
 End If
 UpdateTeilnehmer(xText)
 Case "Set_Lauf"
 xText = Mid(Message,10)
 If xText = "ALLE" Then
 SendeAlleLauf(user)
 End If
 Case "In_Zeit1"
 xText = Mid(Message,9)
 IncomingZeit1(xText)
 Case "In_Zeit2"
 xText = Mid(Message,9)
 IncomingZeit2(xText)
 Case "In_Platz"
 xText = Mid(Message,9)
 IncomingPlatz(xText)
 ...
 End Select
 End Sub
 | 
 
 Private Mitteilung könnte ich auch einbauen...habe ich aber keinen Bedarf für.
 
 Und ein
 
  	  | Code: |  	  | TSNEPlay_SendMSG(0, xText ) | 
 sendet z.B. die Nachricht immer an alle Clients ... z.B. für die Zu- und Abgänge in der Userliste.
 Oder auch für den Kartenzug...wenn den nämlich alle Clients mitgeteilt bekommen, könnte der schauen, ob das sein Spiel betrifft. wenn nicht halt verwerfen den Kartenzug...-> das würde auch gleichzeitig die Möglichkeit eröffnen sowas wie Beobachter eines Spiels einbauen zu können.
 
 Wie dem auch sei. Ich glaube nicht das das so schwer umzusetzen wäre. Das schwieriger scheint mir ehr zu sein, das Du dich innerlich umstellen musst.
 Ich kenne das von mir.... ich hatte immer noch (oder habe vielleicht auch noch teilweise) VB 6 im Hinterkopf...da konnte man alles mögliche quasi im Schlaf realisieren..(wenn es denn nicht zügig laufen solll
  ) 
 Grüße
 Rainer
 |  |  
		| Nach oben |  |  
		|  |  
		| stevie1401 
 
 
 Anmeldungsdatum: 04.07.2006
 Beiträge: 133
 
 
 | 
			
				|  Verfasst am: 08.12.2012, 15:41    Titel: |   |  
				| 
 |  
				| Hallo Rainer, vielen Dank für deine Hilfe.
 Ich bin nun etwas verblüfft.
 Ich darf in der checkMessage() mit Dim Shared Variablen arbeiten???
 Denn genau darum geht es ja. Es wird geprüft, was gerade anfällt.
 Verläßt z.B. Spieler "Stevie" einen Tisch wird folgendes geprüft:
 For i=1 to TischAnz 'TischAnz ist eine DimShared Integervariable
 For j=1 to 4
 If TischSpieler(i,j)="Stevie" then  'TischSpieler() ist ein Dim Shared String
 TischSpieler(i,j)="frei"
 TischNr=i
 End If
 Next j
 Next i
 If TischNr>0 then
 sendeAnAlleSpielerVonTisch(TischNr,"Stevie hat den Tisch verlassen")
 End if
 
 
 Das war jetzt nur mal ein Beispiel.
 DAS darf ich also problemlos in der sub checkmessage schreiben ohne
 MUTEXLOCK
 MUTEXUnLOCK
 machen zu müssen? Wieso das denn plötzlich???
 |  |  
		| Nach oben |  |  
		|  |  
		| RWK 
 
 
 Anmeldungsdatum: 04.07.2011
 Beiträge: 44
 
 
 | 
			
				|  Verfasst am: 08.12.2012, 15:55    Titel: |   |  
				| 
 |  
				|  	  | Code: |  	  | Case "Get_Teil" xText = Mid(Message,10)
 Do
 If xtext = teilnehmerdb(x,0) Then
 xText = "Get_Teil:" & teilnehmerDB(x,2) & " " & teilnehmerDB(x,1) & Chr(13) & Chr(10) & TeilnehmerDB(x,3) & " -- " & teilnehmerDB(x,9)
 Exit Do
 End If
 x = x + 1
 Loop Until teilnehmerdb(x,0) = ""
 If Left(xText,1) <> "G" Then
 xText = "Get_Teil:" & "Nummer nicht gefunden!"
 End If
 TSNEPlay_SendMSG(User, xText)
 | 
 
 Ist ja nichts anderes als hier.... der Moderator fragt nach Teilnehmernummer z.B. 517...
 ich guck in der Datenbank nach der Nummer...wenn gefunden baue ich einen String zusammen und schicke den an den Moderator (User) zurück.
 
 live getestet ist das bis jetzt nur bei so ca. 600 Teilnehmern...keine Probleme.
 
 Das klappt deswegen, weil ich mich nicht mehr in der CallBackroutine von TSNE befinde. Darum auch mein Umweg aus der TSNEPlay_Message Sub..die ja das Callback von TSNE bei Dateneingang ist....einfach die Nachricht an eine eigene Sub weiterzuleiten.
 
 Das ganze in der CallBack Routine verarbeitet crasht das Programm.
 |  |  
		| Nach oben |  |  
		|  |  
		| stevie1401 
 
 
 Anmeldungsdatum: 04.07.2006
 Beiträge: 133
 
 
 | 
			
				|  Verfasst am: 08.12.2012, 18:37    Titel: |   |  
				| 
 |  
				| Okay, das teste ich mal, das wäre ja echt der Hit^^ Vielen Dank
  |  |  
		| Nach oben |  |  
		|  |  
		|  |  
  
	| 
 
 | Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten.
 Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
 Du kannst deine Beiträge in diesem Forum nicht löschen.
 Du kannst an Umfragen in diesem Forum nicht mitmachen.
 
 |  |