Brauche hilfe bei send un recv(Winsock)



  • hi ich habe jetzt mal mit der netzwerkprogrammierung sprich winsocket angefangen.
    Ich habe das erste kapitel von http://www.c-worker.ch/winsock/index.php durch gearbeitet und i-wie hab ich das gefühl da ich die methoden send und recv nicht so ganz verstehe. Also ich habe den Server und den Client soweit gebraucht das sie eine verbindung aufbauen können doch wenn ich jetzt etwas senden möchte und es dan ausgebe kommt etwas ganz anderes bei raus ich hab jetzt mal den wert von recv auf -1 überprüft und ja das ist er auch aber ich habe keine ahnung woran das liegen könnte

    Hier mal der Server

    [code]
    
    #include <winsock.h>
    #include <winsock2.h>
    #include <stdio.h>
    #include <iostream>
    //Prototypen
    using namespace std;
    int startWinsock(void);
    
    int main()
    {
      long rc;
      SOCKET acceptSocket; // Socket definieren
      SOCKET connectedSocket;
      SOCKADDR_IN addr;//wir nemen sockaddr_in für internet das sind nur typdefs
      char buf[256];
    
      rc=startWinsock();
    
      // ------überprüft ob der winsock gestartet wurde
    
      if(rc!=0)
      {
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
        return 1;
      }
      else
      {
        printf("Winsock gestartet!\n");
      }
    
      //  --------------------------------------------
    
      //  ------überprüft ob der Socket erstellt wurde bzw. erstellt ihn
    
      acceptSocket=socket(AF_INET,SOCK_STREAM,0);//den eigentlichen socket erstellen
      //1.Param Adressfamilie TCP/IP = AF_INET
      //2.Param Socket Typ  TCP = SOCK_STREAM
      //3.Param Protokoll
      //fals socket nicht erstelltwurde rückgabewert = INVALID_SOCKET
    
      if(acceptSocket==INVALID_SOCKET)
      {
        printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
        //WSAGetLastError(); gibt einen fehlercoder zurück der abgefragt wird
        return 1;
      }
      else
      {
        printf("Socket erstellt!\n");
      }
    
      //   --------------------------------------------
    
      // ------Socket Binden
    
      memset(&addr,0,sizeof(SOCKADDR_IN));
    
      addr.sin_family=AF_INET; //gleich
      addr.sin_port=htons(12345);//port an den wir den socket binden sollen
      addr.sin_addr.s_addr=INADDR_ANY;//von jeder Adresse
    
      rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));//Socket bekommt normal einen zufallsport hiermit kann man den socket an einen port binden
      //1.Param Socket den wir an einen port binden wollen
      //2.Param Adressfamilie wieder AF_INET
      //3.Param größe der strucktur im 2ten param
      //Error: SOCKET_ERROR
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: bind, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Socket an port 12345 gebunden\n");
      }
    
      //-----------------------------------------------------------
    
      // ------ Auf Verbindung warten
    
      rc=listen(acceptSocket,10);//auf verbindung warten
      //1. Param Socket der auf verbindung warten soll
      //2. Param Anzahl der maximalen verbindungen
      //Error: SOCKET_ERROR
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: listen, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("acceptSocket ist im listen Modus....\n"); 
      }
    
      //-------------------------------------------------------------
    
      // ------ Akzeptieren
    
      connectedSocket=accept(acceptSocket,NULL,NULL);//Verbindung Akzeptieren
      //1.Param Socket desen Verbindung Akzeptiert werden soll 
      //2.Param optional, ein Pointer auf eine SOCKADDR Strucktur in welchem die IP Adresse, etc. des Clients, der eine Verbindung hergestellt hatt, gespeichert werden, verwenden wir hier nicht.
      //3.Param optional, Pointer in welchem die Länge von addr gespeichert wird, verwenden wir hier nicht. 
      //Error: INVALID_SOCKET
    
      if(connectedSocket==INVALID_SOCKET)
      {
        printf("Fehler: accept, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Neue Verbindung wurde akzeptiert!\n");    
      }
    
      // ------------------------------------------------------------  
      rc=recv(acceptSocket,buf,256,0);
      if(rc == -1)
      {
            cout<<"fail"<<endl;
      }
      buf[rc]='\0'; 
      cout<<buf<<endl;
    
      cin.get();
      return 0;
    }
    
    // Das ist beim server auch gleich
    int startWinsock(void)
    {
      WSADATA wsa;
      return WSAStartup(MAKEWORD(2,0),&wsa);
      //Solange diese Fkt. nicht erfolgreich ausgeführt wurde können keine Socket Fkt. benutzt werden                               //
      //----------------------------------------------------------------------------------------------------------------------------//
      //1. Param Winsockversion wird festgelegt                                  funktioniert am besten mit MAKEWORD(hob,lob)       //
      //Im high order byte wir die Minor und im low order byte die Major Versionsnummer angegeben                                   //
      //----------------------------------------------------------------------------------------------------------------------------//
      //2. Param Pointer auf eine Struktur vom Typ WSADATA übergeben                                                                //                                                                                                                         //
    
    }
    
    [/code]
    

    Und hier der Client

    [code]
    
    #include <winsock.h>
    #include <winsock2.h>
    #include <stdio.h>
    #include <iostream>
    //Prototypen
    using namespace std;
    int startWinsock(void);
    
    int main()
    {
      long rc;
      SOCKET acceptSocket; // Socket definieren
      SOCKET connectedSocket;
      SOCKADDR_IN addr;//wir nemen sockaddr_in für internet das sind nur typdefs
      char buf[256];
    
      rc=startWinsock();
    
      // ------überprüft ob der winsock gestartet wurde
    
      if(rc!=0)
      {
        printf("Fehler: startWinsock, fehler code: %d\n",rc);
        return 1;
      }
      else
      {
        printf("Winsock gestartet!\n");
      }
    
      //  --------------------------------------------
    
      //  ------überprüft ob der Socket erstellt wurde bzw. erstellt ihn
    
      acceptSocket=socket(AF_INET,SOCK_STREAM,0);//den eigentlichen socket erstellen
      //1.Param Adressfamilie TCP/IP = AF_INET
      //2.Param Socket Typ  TCP = SOCK_STREAM
      //3.Param Protokoll
      //fals socket nicht erstelltwurde rückgabewert = INVALID_SOCKET
    
      if(acceptSocket==INVALID_SOCKET)
      {
        printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());
        //WSAGetLastError(); gibt einen fehlercoder zurück der abgefragt wird
        return 1;
      }
      else
      {
        printf("Socket erstellt!\n");
      }
    
      //   --------------------------------------------
    
      // ------Socket Binden
    
      memset(&addr,0,sizeof(SOCKADDR_IN));
    
      addr.sin_family=AF_INET; //gleich
      addr.sin_port=htons(12345);//port an den wir den socket binden sollen
      addr.sin_addr.s_addr=INADDR_ANY;//von jeder Adresse
    
      rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));//Socket bekommt normal einen zufallsport hiermit kann man den socket an einen port binden
      //1.Param Socket den wir an einen port binden wollen
      //2.Param Adressfamilie wieder AF_INET
      //3.Param größe der strucktur im 2ten param
      //Error: SOCKET_ERROR
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: bind, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Socket an port 12345 gebunden\n");
      }
    
      //-----------------------------------------------------------
    
      // ------ Auf Verbindung warten
    
      rc=listen(acceptSocket,10);//auf verbindung warten
      //1. Param Socket der auf verbindung warten soll
      //2. Param Anzahl der maximalen verbindungen
      //Error: SOCKET_ERROR
      if(rc==SOCKET_ERROR)
      {
        printf("Fehler: listen, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("acceptSocket ist im listen Modus....\n"); 
      }
    
      //-------------------------------------------------------------
    
      // ------ Akzeptieren
    
      connectedSocket=accept(acceptSocket,NULL,NULL);//Verbindung Akzeptieren
      //1.Param Socket desen Verbindung Akzeptiert werden soll 
      //2.Param optional, ein Pointer auf eine SOCKADDR Strucktur in welchem die IP Adresse, etc. des Clients, der eine Verbindung hergestellt hatt, gespeichert werden, verwenden wir hier nicht.
      //3.Param optional, Pointer in welchem die Länge von addr gespeichert wird, verwenden wir hier nicht. 
      //Error: INVALID_SOCKET
    
      if(connectedSocket==INVALID_SOCKET)
      {
        printf("Fehler: accept, fehler code: %d\n",WSAGetLastError());
        return 1;
      }
      else
      {
        printf("Neue Verbindung wurde akzeptiert!\n");    
      }
    
      // ------------------------------------------------------------  
      rc=recv(acceptSocket,buf,256,0);
      if(rc == -1)
      {
            cout<<"fail"<<endl;
      }
      buf[rc]='\0'; 
      cout<<buf<<endl;
    
      cin.get();
      return 0;
    }
    
    // Das ist beim server auch gleich
    int startWinsock(void)
    {
      WSADATA wsa;
      return WSAStartup(MAKEWORD(2,0),&wsa);
      //Solange diese Fkt. nicht erfolgreich ausgeführt wurde können keine Socket Fkt. benutzt werden                               //
      //----------------------------------------------------------------------------------------------------------------------------//
      //1. Param Winsockversion wird festgelegt                                  funktioniert am besten mit MAKEWORD(hob,lob)       //
      //Im high order byte wir die Minor und im low order byte die Major Versionsnummer angegeben                                   //
      //----------------------------------------------------------------------------------------------------------------------------//
      //2. Param Pointer auf eine Struktur vom Typ WSADATA übergeben                                                                //                                                                                                                         //
    
    }
    
    [/code]
    


  • Du musst recv und send einen Socket übergeben, auf dem eine gültige Verbindung besteht ..
    Kurzer Abriss zur Funktion accept: Man übgergibt accept den Socket, der die nötigen Verbindungsdaten hat und auf dem gerade eine gültige Anfrage für eine Verbindung vorhanden ist und als Rückgabewert erhält man dann ein Handle auf ein Socket, der die nun aufgebaute Verbindung beinhaltet. Also musst du zum Senden und Empfangen den durch accept zurückgegebenden Socket benutzen. Du benutzt aber den Socket, den du durch accept jagst.
    Dann noch: Der Client braucht kein accept, sondern nur connect.
    Dabei ist der Server bereits im listen-Modus (wartet auf eine Verbindung) und der Client stellt per connect eine Anfrage an die entsprechende Stelle (also was du in der SOCKADDR angegeben hast). Der Server springt aus dem listen-Modus raus, weil eine Anfrage besteht und geht nun zum accept über, prüft also, ob die einkommende Verbindung valid ist. Nach dem alles gut ist, gibt beim Server accept den neuen Socket zurück (wie oben beschrieben) und beim Client füllt connect den angegebenen Socket mit dem neu verbundenem Socket. Wenn der Client mit connect nicht erfolgreich ist, dann gibts SOCKET_ERROR als Rückgabewert.



  • Okey danke ich versuchs gleich mal



  • Juhu danke es klappt das mir dem connected socket war der fehler hab des voll verpeilt danke nochma mfg Dagnih ^^



  • Hast du auch mal probiert, beim Client das accept wegzulassen? Sollte nämlich dann auch gehen, weil accept eig. nichts mit dem Socket machen dürfte, der Aufruf also rudimentär ist.



  • ne mach ich jetzt aber ich hab bloss eig den client geschrieben , danach den server und hab dan i-wie ausversehen den client gelöscht deshalb hab ich dan mithilfe des servercodes wieder den client erstellt und da ja alles bis auf des send bzw recv funktioniert hat is mir dan auch net aufgefallen danke nochmal

    mfg Dagnih



  • achso achso, gut dann hat sich das ja geklärt ^^
    kein problem x)



  • Okey, ich weiß jetzt jetzt woran es liegt ich habe irgendwie dummerweise 2 mal den server gepostet anstatt server und client 😃



  • sehr gut 😃 problem konnte ja trotzdem gelöst werden 😛



  • jop :p


Anmelden zum Antworten