Frage zu WinSock Client



  • Hallo ich habe folgendes Problem:

    Ich starten den Server dann den Client dann sende ich vom Client an den Server z.b. den Text 123

    Der Server sendet mir dann zurück: tes

    Aber wenn ich beim Client

    SOCKET Empfang;
    

    nicht deklariere dann tritt das Problem nicht auf woran könnte das liegen ?

    Client:

    #include <windows.h>
    #include <iostream.h>
    using namespace std;
    
    int main()
    
    {
    
    char buf2[256];
    
    string ip;
    long rc;
    char buf[256];
    int nret;
    
    SOCKET kSock;
    SOCKET Empfang;
    
    WSAData wsdata; 
    WORD wsver=MAKEWORD(2, 0);
    
    nret=WSAStartup(wsver, &wsdata);
    
    kSock=socket(AF_INET, SOCK_STREAM, 0);
    
    sockaddr_in sin;
    sin.sin_port=htons(12345);
    sin.sin_addr.s_addr=inet_addr("127.0.0.1");
    sin.sin_family=AF_INET;
    
    rc = connect(kSock,(sockaddr*)&sin, sizeof(sin));
    
     while(rc!=SOCKET_ERROR)
      {
    
          cout<<"\nZeichenfolge eingeben [max 256]: ";
          cin>>buf;
    
                  send(kSock,buf,strlen(buf),0);
                  recv(kSock, buf2, strlen(buf2), 0);
    
          cout<<"Server Antwortet: "<<buf2;
    
      }
    
    system("PAUSE");
    
    closesocket(kSock);
    return 0;
    }
    

    Server

    #include <windows.h>
    #include <conio>
    #include <iostream>
    using namespace std;
    
    int main()
    {
    
    char buf[256] = "\0";
    char buf2[256]= "test";
    
    long rc;
    
    SOCKET kSock;
    SOCKET client;
    
    int len;
    
    string change_mode;
    
    WSAData wsdata;
    WORD wsver=MAKEWORD(2, 0);
    int nret=WSAStartup(wsver, &wsdata);
    
    kSock=socket(AF_INET, SOCK_STREAM, 0);
    
    sockaddr_in sin;
    sin.sin_port=htons(12345);
    sin.sin_addr.s_addr=INADDR_ANY;
    sin.sin_family=AF_INET;
    
    	bind(kSock,(sockaddr*)&sin, sizeof(sin));
            rc=listen(kSock,10);
            client=accept(kSock,NULL,NULL);
    
      while(rc!=SOCKET_ERROR)
      {
    
               send(client,buf2,strlen(buf2),0);
               rc=recv(client,buf,256,0);
    
              cout<<"Client sendet: "<<buf<<endl;
       }
    
    system("PAUSE");
    
    closesocket(client);
    closesocket(kSock);
    
    WSACleanup();
    return 0;
    }
    


  • Gib im Client mal

    strlen(buf2) aus, diese Länge ist doch völlig undefiniert ...



  • Ist immer dasselbe:
    recv(..) liest nicht zwingend in einem mal dein String. Das bedeutet, dass dein buf2 nicht zwingend null terminiert ist, was sehr schlecht ist für Ausgabefunktionen wie std::cout.

    Das Vorgehen muss so sein:
    so viele male recv(..) aufrufen, bis die Anzahl empfangenen Zeichen stimmt oder eben das terminierende null empfangen wurde. DANN erst den String ausgeben.

    Ausserdem wie schon von Belli angemerkt ist strlen mit nicht initialisierten buffern sehr schlecht (undefiniertes Verhalten).

    Löse dich von gedanken strings zu senden / empfangen. Es geht um bytes.
    Die KÖNNEN dann zu strings zusammengesetzt werden.

    Simon

    Edit:
    Hab nicht mal die Frage gelesen. Aber ich schätze mal ich bin auf ein Troll Versuch reingefallen... 🕶



  • Troll ? Das hier ist kein Troll Thread ! 😡

    So ich habs hinbekommen:

    Client:

    #include <windows.h>
    #include <iostream.h>
    using namespace std;
    
    int main()
    
    {
    
    char buf2[256];
    long rc;
    long since;
    
    char buf[256];
    
    SOCKET kSock;
    SOCKET emp;
    
    WSAData wsdata;
    WORD wsver=MAKEWORD(2, 0);
    
    WSAStartup(wsver, &wsdata);
    
    kSock=socket(AF_INET, SOCK_STREAM, 0);
    
    sockaddr_in sin;
    sin.sin_port=htons(12345);
    sin.sin_addr.s_addr=inet_addr("127.0.0.1");
    sin.sin_family=AF_INET;
    
    rc = connect(kSock,(sockaddr*)&sin, sizeof(sin));
    
     while( rc != SOCKET_ERROR)
     {
          cout<<"\nZeichenfolge eingeben [max 256]: ";
          cin>>buf;
    
          send(kSock,buf,256,0);
    
          // recv  If no error occurs, recv returns the number of bytes received.
          since  = recv(kSock, buf2, 256, 0);  // since gib aus wie viele zeichen empfangen wurden
    
          buf2[since]='\0';  // man kann auch schreiben buf[4]='\0'; wenn man weiss das der server
                            // immer nur 4 bytes versendet
    
          cout<<"Server Antwort: "<<buf2<<endl;
    
     }
    
    system("PAUSE");
    
    closesocket(kSock);
    return 0;
    }
    


  • Eine Frage habe ich noch zum Server

    Muss ich

    buf
    

    auch nochmal 0 Terminieren ?

    Also es funktioniert ohne 0 Terminierung aber ist das auch sinnvoll oder er egal ?

    [/cpp]
    while(rc!=SOCKET_ERROR)
    {

    send(client,buf2,strlen(buf2),0);
    rc = recv(client,buf,256,0);

    // buf[rc] = '\0'; <-- ist es sinnvoll das hier zu 0 terminieren?
    cout<<"Client sendet: "<<buf<<endl;
    }

    [/cpp]


Anmelden zum Antworten