ServerSocket



  • Hi!

    Ich schreib zur Zeit an einem MultiUserChat (BCB6 ohne Indy - Server und CLient als einzelne Anwendungen), jetzt hab ich aber ein paar Fragen zum ServerSocket:

    1. Gibt es ein Möglichkeit die maximale Anzahl an Verbindungen zu begrenzen? Ich mach das zur Zeit so:
      Ich hab ein TEditbox in der der User die maximale Anzahl an Usern angibt, zudem wird jeder neue User in eine TListBox eingetragen.
    void __fastcall TfrmApmChatServer::ServerSocketAccept(TObject *Sender,
          TCustomWinSocket *Socket)
    {
            if(ServerSocket->Socket->ActiveConnections > edtMaxUser->Text.ToInt())
                    ServerSocket->Socket->Lock();
            lboxUser->Items->Add((ServerSocket->Socket->Connections[lboxUser->Count]->RemoteAddress));
    }
    
    void __fastcall TfrmApmChatServer::ServerSocketClientDisconnect(
          TObject *Sender, TCustomWinSocket *Socket)
    {
            if(ServerSocket->Socket->ActiveConnections < edtMaxUser->Text.ToInt())
                    ServerSocket->Socket->Unlock();
    
    }
    
    1. Gibt es eine Möglichkeit außer der IP noch mehr über den Client zu erfahren (ohne dass ich das ganze als Protokollfunktion implementiere), also etwas in der Art wie
    lboxUser->Items->Add((ServerSocket->Socket->Connections[lboxUser->Count]->RemoteAddress));
    für Username, usw.
    

    3)Hat jemand von euch erfahrung mit Chatprotokollen? Ich suche ein einfaches Verfahren, d.h. keine Emotions oder ähnliches. Das Problem ist, dass der Datentransfer verschlüsselt wird, daher kann ich nicht auf die **Standardprotokolle zurüggreiffen. Wenn z.B. Client A eine Nachricht abschickt, verschlüsselt er sie per symmetrischer Verschlüsselung und schickt die Daten an den Server, der verteilt sie dann an die anderen Clienten, welche dann die Daten wieder entschlüsseln.
    Ich dachte daran, dass die die ersten 8 Byte für den Header reserviert werden. Der Server schaut sich die an, wobei M für Nachicht Msg) und O für Befehl (Order) steht. Kommt eine Nachricht mit M vorne dran, setzt der Server noch den Username vornedran und senden alles zusammen an die anderen Clienten. Bei Befehlen, verwaltet er sie selber.
    Oder hat jemand von euch eine bessere Idee?
    4) Wie kann abfragen, welcher User gerade disconnectet hat? D.h. ich möchte diesen User dann aus der TListBox löschen. ich hab schon überlegt ob ich vieleicht einfach einen Thread für jeden User mache. Aber eigentlich macht das ja auch schon die ServerSocket-Klasse. Irgendwelche Vorschläge?

    Schon einmal Danke!
    Grüße
    Kronos**



    1. Nein, du musst selbst Buch führen, wieviele Verbindungen du geöffnet hast.
    2. Nein, musst du selbst implementieren (siehe 4).
    3. ZB. anhand einer Zuordnung von IP-Adressen zu Benutzernamen, die du in die "Buchführung" aus 1) mit aufnimmst. Das Ganze nennt sich dann Benutzerverwaltung, sowas brauchst du auf dem Server ohnehin.


  • Das mit der Benutzerverwaltung ist schon klar, aber wie sollte ich das am besten machen? Am besten wäre doch, dass ich über einen PseudoZufallsgenerator jedem User eine SitzungsID zuordne.

    [ Dieser Beitrag wurde am 04.01.2003 um 16:26 Uhr von Kronos_1 editiert. ]



  • Was ist dann besser?
    Ich programmiere eine eigene WinSock-Implementation oder ich benutze die ServerSockets?



  • Zum Thema Benutzererkennung hast du eben deine Frage ja selber beantwortet. ->Session ID

    zu 3) Du kannst doch auch standardprotokolle verwenden und den Stream einfach verschlüsseln? In OSI/ISO Modell gesprochen wäre das dann einfach eine weitere Schicht die du zwischen Layer 4 und 5 (wars glaub ich) schiebst. Oder anders ausgedrückt: Leite von TServerSocket eine Klasse ab (z.B. TSecureServerSocket) überschreib die Send- und Receive-Methoden mit eigenen in denen du die Daten ent- bzw. verschlüsselst und fertig. Für den Schlüsselaustausch kannst du ja immernoch Funktionen bereitstellen oder bei den Sendefunktionen ein Flag einfügen ob der Text verschlüsselt werden soll oder nicht.

    Ob WinSock oder TServerSocket besser ist musst du selber entscheiden. TServerSocket ist einfacher zu handhaben und komfortabler. Ausserdem ist das bereits ein WinSock wrapper... also wieso nochmal alles zu fuss machen? (-;

    -junix



  • Original erstellt von junix:
    **Zum Thema Benutzererkennung hast du eben deine Frage ja selber beantwortet. ->Session ID

    zu 3) Du kannst doch auch standardprotokolle verwenden und den Stream einfach verschlüsseln? In OSI/ISO Modell gesprochen wäre das dann einfach eine weitere Schicht die du zwischen Layer 4 und 5 (wars glaub ich) schiebst. Oder anders ausgedrückt: Leite von TServerSocket eine Klasse ab (z.B. TSecureServerSocket) überschreib die Send- und Receive-Methoden mit eigenen in denen du die Daten ent- bzw. verschlüsselst und fertig. Für den Schlüsselaustausch kannst du ja immernoch Funktionen bereitstellen oder bei den Sendefunktionen ein Flag einfügen ob der Text verschlüsselt werden soll oder nicht.

    Ob WinSock oder TServerSocket besser ist musst du selber entscheiden. TServerSocket ist einfacher zu handhaben und komfortabler. Ausserdem ist das bereits ein WinSock wrapper... also wieso nochmal alles zu fuss machen? (-;

    -junix**

    Das mit der Verschlüsselung ist kein Problem. Der Schlüsselaustausch funktioniert über eine Hybrideverschlüsselung. Die Verschlüsselung selbst hab ich auch schon ohne Probleme implementiert.

    Du kannst doch auch standardprotokolle verwenden

    An welche denkst du dabei?

    Hat jemand vieleicht einen guten Sourcecode für die Benutzerverwaltung?

    [ Dieser Beitrag wurde am 04.01.2003 um 16:46 Uhr von Kronos_1 editiert. ]



    • http://learn.to/quote
    • IRC, Telnet, SSH, klassisches HTTP etc. pp Natürlich kannst du auch diese Protokolle abändern oder reduzieren... Aber als Basis würde ich eine Standard-Lösung vorshclagen. Damit musst du dich nicht mit Problemen rumschlagen die die Protokollentwicklung "from scratch" mit sich bringt.
      Andererseits ist die Definition eines eigenen Protokolls natürlich auch eine gute Übung. Musst du selber entscheiden. Vielleicht auch ein eigenes Protokoll aber mit TCP/IP ähnlichem Frameaufbau... wie gesagt. Du bist frei (:
    • Was meinst du mit "Benutzerverwaltung"?

    -junix



  • http://learn.to/quote

    Sollte das eine Anspielung sein? Ich verstehe nicht ganz den Zusammenhang. Was hat zitieren mit Sockets bzw. Protokollen zu tun 😕

    Was meinst du mit "Benutzerverwaltung"?

    Mit Benutzerverwaltung meine ich, dass jeder User wenn er sich am Server anmeldet, eine SessionID erhält. Der Server weiß jetzt immer wer wohin eine Nachricht geschickt hat. Der Server verwaltet jeden User, indem er per digitaler Unterschrift nachprüft, ob der Client "echt" ist. Das ganze soll dann darauf hinauslaufen, dass ich ein MySql Datenbank benutze, indem jeder User später angemeldet ist.
    -> Es wird zwei "Benutzerverwaltungen" geben

    • temporäre: Dient nur dazu die Benutzer zu identifizieren (s.o.)
    • interne: Dient dazu den User zu authentifizieren usw.

    Danke übrigens für eure schnellen Antworten! 🙂

    [ Dieser Beitrag wurde am 04.01.2003 um 19:28 Uhr von Kronos_1 editiert. ]



  • Lies mal was unter der URL steht und schau dir nochmal den Beitrag vom 04.01.2003/16:44 an.
    Soviel dazu.

    Was die Benutzerverwaltung anbetrifft so wirst du sowas komplexes vermutlich kaum finden - oder jemanden Finden der dir den Source einfach so zur Verfügung stellt. Wenn wir mal ehrlich sind, ists auch nicht so komplex (-; Reine Fleissarbeit (:

    -junix



  • Lies mal was unter der URL steht und schau dir nochmal den Beitrag vom 04.01.2003/16:44 an.
    Soviel dazu.

    Axo, Sorry, hab ich dich falsch verstanden 🙂

    Was die Benutzerverwaltung anbetrifft so wirst du sowas komplexes vermutlich kaum finden - oder jemanden Finden der dir den Source einfach so zur Verfügung stellt. Wenn wir mal ehrlich sind, ists auch nicht so komplex (-; Reine Fleissarbeit (:

    Ja glaub ich jetzt auch. Da werd ich mich wohl morgen mal hinsetzen müssen. Naja, ok. Danke auf jeden Fall.
    Noch eine Frage, hat jemand von euch noch eine gute Dokumentation zu ServerSockets (zusätzlich zur BCB Hilfe) ?

    [ Dieser Beitrag wurde am 04.01.2003 um 20:48 Uhr von Kronos_1 editiert. ]



  • Jo in meinem Kopf (:

    Was hast du für Probleme?

    -junix



  • Danke 🙂
    Ich werde vermutlich morgen auf dein Angebot zurückkommen.

    [ Dieser Beitrag wurde am 04.01.2003 um 21:49 Uhr von Kronos_1 editiert. ]



  • Also zur Benutzerverwaltung brauchste doch nur den Socket mit in die Listbox nehmen dort kann man jedem String ein Object hinzufügen, somit kannst du auch gleich feststellen welcher Client connected/disconected/sendet usw.

    Das ist das einfachste das ich kenne.
    Du kannst auch andere Objekte einfügen z.B. Thread ID's usw.

    Das hat auch den Vorteil z.B. mit den Sockets das sich auch Benutzer mit dem sleben Namen anmelden können da ja der Socket individuell ist d.h. für jeden Client ein eigener erzeugt wird.

    Damit lässt sich sicher einiges anfangen.



  • Also zur Benutzerverwaltung brauchste doch nur den Socket mit in die Listbox nehmen dort kann man jedem String ein Object hinzufügen, somit kannst du auch gleich feststellen welcher Client connected/disconected/sendet usw.

    Wie du vieleicht im Sourcecode oben bei mir gesehn hast, arbeite ich zurzeit mit einer TListBox, das Problem ist jedoch, dass ich so nicht bestimmten kann, wer disconnected hat. Ich werde jetzt vermutlich jedem User einen eigenen Thread zuordnen und eine SessionID vergeben.
    Aber trotzdem danke für den Tipp!



  • Original erstellt von Kronos_1:
    [...]das Problem ist jedoch, dass ich so nicht bestimmten kann, wer disconnected hat. [...]

    Ach... und du bist dir da auch ganz sicher? Ich sehe vor meinem geistigen Auge nochmals die Ereignisse von TServerSocket nochmal genau ansehen (-;

    FoxAlphas Vorschlag ist durchaus gut, nur musst du bedenken, dass du die Zeiger aus der ListBox nullst, wenn sich jmd disconnectet oder der ganze ServerSocket geschlosen wird.

    Ich denke wenn du allerdings von TServerSocket eine Ableitung machst, welcher du eine TListBox übergeben kannst (und die z.B. das Ganze Protokoll behandelt) dürftest du am sichersten fahren.

    -junix



  • Also ich verwende meinen Vorschlag ebenfalls in einem Chat und das klappt wunderbar.
    Ich habe das so gemacht :

    Zum Connecten ->

    TListBoxItem *newItem;
        newItem = FMain->clbSvrList->ListBoxItems->Add();
        newItem->ImageIndex = ClnStatus;
        newItem->Strings->AddObject(ClnName, WSocket);
        newItem->Strings->Add("( PING )");
    

    Beim Disconnect ->

    void __fastcall TClientThrd::DelFromList()
    {
        TWSocket *DelSock;
        csServer->Enter();
        //Object suchen und aus liste entfernen
        int Index, i;
        if(FMain->clbSvrList->ListBoxItems->Count==0)
        {
            csServer->Leave();
            return;
        }
    
        for(i=0;i<FMain->clbSvrList->ListBoxItems->Count;i++)
        {
            if((Index = FMain->clbSvrList->ListBoxItems->Items[i]->Strings->IndexOfObject(WSocket))!=-1)
                break;
        }
    
        if(Index != -1)
        {
            DelSock = (TWSocket *)FMain->clbSvrList->ListBoxItems->Items[Index]->Strings->Objects[Index];
            if(DelSock)
                DelSock->Close();
    
            FMain->clbSvrList->Update();
            FMain->clbSvrList->ListBoxItems->Delete(Index);
    //        FMain->clbSvrList->Items->Objects[Index] = NULL;
        }
        DelSock = NULL;
        csServer->Leave();
    }
    

    Ich benutze es zwar in Threads, was vor- und Nachteile hat.

    Meine Listbox hat 3 Spalten wie man sehen kann
    1. Icon für den Status (ICQ like 🙂 )
    2. den Namen des Client
    3. Den Ping vom Server zum Client

    Wie gsagt bei mir klappts wunderbar


Anmelden zum Antworten