[Winsock] Hilfe bei Chat Server



  • Ich bin grade dabei einen Server in C zu schreiben.
    Nur leider wartet er nicht auf Verbindungen:

    int verbindung()
    {
     WSADATA wdData;
      if (WSAStartup(MAKEWORD(2, 0), &wdData) == INVALID_SOCKET) {
        printf ("Konnte WinSock nicht initialisieren!\n");
        system ("PAUSE");
        return 256;                   
      } else {
        printf("WinSock initialisiert!\n");
      }
    
      SOCKET sckSocket;
      SOCKADDR_IN addrServer;
      char Request[100];
    
      /* SOCKADDR_IN erstellen und Port setzen, auf dem er hört. */
      addrServer.sin_addr.s_addr = INADDR_ANY; // listen on all IPs associated with this computer
      addrServer.sin_port = htons(130); 
      addrServer.sin_family = AF_INET;
    
      if ((sckSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
        printf ("Konnte keinen Socket erstellen!\n");
        system ("PAUSE");
        return 256;
      } else {
        printf ("Socket erstellt!\n");
      }
    
      if (bind(sckSocket, (SOCKADDR *) &addrServer, sizeof(addrServer)) == SOCKET_ERROR) {
        printf  ("Konnte nicht an Port binden!\n");
        system ("PAUSE");
        return 254;
      } else {
        printf("An Port gebunden!\n");   
      }
    
      if (listen(sckSocket, 4) == SOCKET_ERROR) {
       printf ("Socket kann nicht hören!\n");
        system ("PAUSE");
        return 253;
      } else {
        printf  ("Socket hört!\n");       
      }
    
      while (0) {
        /* Zum Ausgrenzen um die Anzahl und schnelligkeit der Durchläufe zu sehen */
    
        SOCKET sckClient = accept(sckSocket, 0, 0);
        if (sckClient != INVALID_SOCKET) {
          /* Nur 1 Strich und kein 'hier müsste was kommen' Also bleibts bei Accept stehen. */
    
          if (recv(sckClient, Request, sizeof(Request), 0) > 0) {
            printf  ("Request\n");
    
            /* Auf Request antworten. */
            char test[] = "hallo zurück";
            send (sckSocket, test, 12, 0);
          }
        }
      }
    
      closesocket (sckSocket);     
    }     
    
    int main (int argc, char* argv[]) 
    {
    verbindung();    
      system ("PAUSE");
      return 0;
    }
    

    wie gesagt wartet er nicht auf Verbindungen.
    Und wie mache ich es,das alles was gesendet wird direkt ausgegeben wird?

    Wäre echt toll wenn mir jemand helfen könnte.

    Mfg
    CHB



  • CHB schrieb:

    wie gesagt wartet er nicht auf Verbindungen.

    Das Programm überspringt die while-Schleife. accept () usw. wird nicht erreicht :

    // while (0) {
    while (1) {     // <- !
    


  • Ich habe deinen Quellcode jetzt mal nur überflogen, doch vielleicht wartet deine Anwendung auf Verbindungen wenn du dem Programm überhaupt einmal die Möglichkeit dazu gibst, indem du es irgendwie einrichtest, dass die whileschleife betreten werden kann.

    Denn dieses while(0) macht alles was in der Schleife steht irgendwie überflüssig 😉

    ---

    Aber mal davon abgesehen.
    Auch wenn dein Programm auf Verbindungen warten wird, glaube ich nicht, dass du etwas damit anfangen kannst.
    Denn wenn eine Verbindung hergestellt wird, wird sie am Ende des Schleifendurchlaufs wieder gelöscht.
    Und da der Client wohl nur einmal versucht sich mit dem Server zu verbinden wirst du danach wohl auch nichts mehr vom Clienten hören.

    ---
    Und wenn du eine Nachricht verschicken möchtest, musst du in der send-funktion den gewünschten Empfänger angeben (also sckClient) und nicht den Sender (hast hier sckServer geschrieben)
    ---
    Für dein Vorhaben würde es sich vielleicht auch lohnen sich die Funktion select() sowie fd_set näher anzuschauen.

    EDIT:
    ui, da war der Merker wohl schneller



  • CHB schrieb:

    SOCKET sckClient = accept(sckSocket, 0, 0);
    

    hältst du das für klug 😕





  • @0_O:
    Was wäre den die bessere Lösung?
    Des is mein erstes Projekt mit Sockets in C.



  • Ok danke habe des jetzt mit der Schleife geändert.
    Aber wenn ich jetzt was hinsende z.B "Hallo" klappt alles.
    Wenn ich aber danach noch was senden will kommt irgendwie nix an.
    Woran liegt das?
    😕 😕 😕



  • Das Problem ist weniger die Funktion selbst als der Ort wo du die benutzt.
    --------

    Schleife beginnt:

    erstelle socket (sckClient)
    Client meldet sich erfolgreich an und der Clientsocket wird erstellt
    (sckClient)

    Empfange nachricht
    Schreib nachricht "zurück"(in wahrheit sendet das Programm hier an sichselbst, da du den falschen Socket angegeben hast)

    Schleife Ende: sckClient wird gelöscht

    Zweiter Durchlauf bis Durchlauf X :

    ertelle neuen Socket (sckClient (v2-x))
    Server versucht einen Clienten anmelden zu lassen, doch leider ohne Erfolg(der Client wird wohl nicht jedes mal versuchen sich beim Server anzumelden)

    Es wird weder versucht eine Nachricht abzufangen noch eine Nachricht zu schreiben.

    Schleifendurchlaufende ... usw

    Soll heißen: Bei dem jetzigen Code hat der Server nur einen Schleifendurchlauf Kontakt mit einem gerade angemeldeten Clienten.

    Abhilfe schafft die Funktion "select"



  • Könntest du mir da ein Codeschnipsel geben?
    Bin noch totaler Anfänger was socktes angeht



  • Ist zwar kein reines C, doch wirst du da bestimmt das nötige rauslesen können.

    http://www.zfx.info/Tutorials.php?ID=84

    Das ist ein Tutorial für einen kompletten Konsolenchat (funktioniert sowohl im Netzwerk als auch über das Internet), doch vor allem einem funktionierendem Chat.

    Falls du so überhaupt nichts mit c++ am Hut hast und auch nicht haben möchtest, dann schaue dir in diesem Tutorial die Funktion "Server::ServerMain" mal an, dort sollten alle relevanten Codeschnipsel drinne sein, auch wenn zum Verständnis das Lesen des restlichen Zeugs nicht schaden würde.



  • Komme damit nicht so richtig klar da ich kein C++ kann.
    Könntest mir jemand meinen C Code richtig umschreiben?



  • Ok danke habe des jetzt mit der Schleife geändert.
    Aber wenn ich jetzt was hinsende z.B "Hallo" klappt alles.
    Wenn ich aber danach noch was senden will kommt irgendwie nix an.
    Woran liegt das?

    Wenn dein Programm zu mindest einmal so geklappt hast wie du es wolltest, scheint die Sache mit dem Clientsocket in der Whileschleife dein einziges Problem sein.
    Doch dafür muss dir keiner was umschreiben, das kannst du auch alleine wenn du so weit gekommen bist.

    Die Deklaration des Clientsocket verschiebst du erst einmal vor die Schleife, sodass der Socket nicht im jeden Schleifendurchlauf gelöscht wird.

    Dort wo jetzt noch die Deklaration des Clientsocket steht musst du prüfen ob eine Nachricht vorhanden ist.

    dafür musst du dich mit der funktion "select" sowie der struktur "fd_set" auseinadnersetzen.
    Das makro FD_ZERO (zur vereinfachung vielleicht auch noch mit FD_SET) wäre sicherlich auch noch ganz gut.

    Kleiner Tipp:
    Wenn sich sich ein Client anmelden möchte, dann taucht der Socket im Listenmodus(sckServer) in der fd_set-struktur auf.



  • Also habe es jetzt so gelöst,das man jetzt beliebige Sachen zum server hinsenden kann.
    Aber wenn ich den client beende.
    Läuft der Server dauernt weiter.
    d.h er gibt verschiedene Nachrichten aus.
    So jetzt hatte vorhin jemand gesagt das wenn ich was an den Client senden will mache ich es völlig verkehrt.
    Wie sende ich den richtig Sachen an den Client?



  • Du schriebst "send(sckServer, blabla)";
    Doch es´muss heißen "send(sckClient, blabla)";



  • So gut ok danke.
    Jetzt hatte ich die Schleife ein bisschen erweitert:

    SOCKET sckClient = accept(sckSocket, 0, 0);
      while (1) {
        /* Zum Ausgrenzen um die Anzahl und schnelligkeit der Durchläufe zu sehen */
        printf ("----\n");
    
        if (sckClient != INVALID_SOCKET) {
          /* Nur 1 Strich und kein 'hier müsste was kommen' Also bleibts bei Accept stehen. */
    
          if (recv(sckClient, Request, sizeof(Request), 0) > 0) {
            printf  ("%s\n",Request);
    
            /* Auf Request antworten. */
            char test[] = "hallo zurück";
            send (sckSocket, test, 12, 0);
          }
        }
      }
    
      closesocket (sckSocket);     
    }
    

    Wenn der Client jetzt aber die Verbindung schließt,kommen mehrere Zeilen -----.
    Wie behebe ich den das?



  • Wenn du den clienten schließt ist sckClient == INVALID_SOCKET, daher wird dieser if-Block mit der Bedingung : sckClient != INVALID_SOCKET übersprungen und die Schleife wird jedes mal einfach aufs neue ausgeführt ohne auf eine Nachricht zu warten.
    Willst dudas verhindern, darfst du die Striche nur ausgeben lassen wenn sckClient ebenfalls != INVALLID_SOCKET ist.



  • Habe des Problem mit den Strichen leider nicht beheben können.
    Aber jetzt kommt schon wieder ein neuer Fehler.
    Ich sende:
    -Test1
    -Test2
    -h
    -Test3
    -A
    -Lol

    Was aber dabei rauskommt ist das:
    -Test1
    -Test2
    -hest2
    -Test3
    -Aest3
    -Lolt3

    Hier der Screen:
    http://img514.imageshack.us/img514/690/lolfd3.jpg





  • Initialisiere "Request" mit 0 vor Aufruf von recv ().



  • if (sckClient != INVALID_SOCKET) 
    {
        printf ("----\n");
    }
    

    Das Problem mit der Ausgabe muss nicht unbedingt am Server liegen, sondern vielleicht auch am Clienten.
    Wenn merkers Tipp das Problem nicht löst wird der wohl auch sein.

    Du verwendest dort für die verschiedenen Nachrichten doch sicherlich den selben string oder?

    Wie befüllstdu den denn?

    Versuche mal den string erst komplett zu leeren bevor du die neue Botschaft reinschreibst oder setze manuell ein '\0' an das Ende deiner gewünschten Nachricht.

    Rein zum testen könntest du auch mal versuchen für das verschicken der verschiedenen Nachrichten verschiedene strings zu verwenden, sollte dieser Fehler dann immer noch auftauchen weißt du zu mindest dass es doch nciht am Clienten liegt 😕 (oder nicht liegen muss).



  • Die Sache is die der Client is in VB6.
    😃

    Glaube eigentlich nicht das es am Client liegt.


Anmelden zum Antworten