c++ Winsock fehler bei send() thread ?



  • Ich habe einen chat client und server programmiert.Mittels threads solln beide in der lage sein daten zu empfangen und die eingabe des benutzers den anderen schicken.

    SERVER:

    //Server
    #include <iostream>
    #include <winsock2.h>
    #include <windows.h>
    
    #define PORT 12345
    
    using namespace std;
    
    long rc;
    char buffers[50];
    string input;
    SOCKET sendsock;
    
    void schicken(SOCKET sock)
    {
        while(1)
        {
            std::getline(std::cin, input);;
            strcpy(buffers,input.c_str());
            rc = send(sock,buffers,input.length(),0);
            if (rc == SOCKET_ERROR)
            {
                cout << "[ERROR]Send fehler."<< WSAGetLastError() << endl;
            } else
            {
                cout << "[INFO]You send: " << input;
        }
        }
    }
    
    void startwinsock()
    {
        WSADATA wsa;
        rc = WSAStartup(MAKEWORD(2,0),&wsa);
        if(rc != 0)
        {
            cout << "[ERROR]Winsock könnte nicht gestarted werden." << endl;
            system("PAUSE");
        } else {
    
            cout << "[INFO]Winsock würde gestarted." << endl;
        }
    }
    
    int main()
    {
        cout << "[INFO]Server wird gestarted." << endl;
        startwinsock();
        SOCKADDR_IN addr;
        SOCKET connectedsocket;
        sendsock = socket(AF_INET,SOCK_STREAM,0);
    
        SOCKADDR_IN clientinfo;
        int clientinfolen = sizeof(clientinfo);
    
        SOCKET acceptsocket = socket(AF_INET,SOCK_STREAM,0);
        if(acceptsocket == INVALID_SOCKET)
        {
            cout << "[ERROR]Socket könnte nicht erstellt werden." << endl;
            system("PAUSE");
        } else{
    
            cout << "[INFO]Socket würde erstellt." << endl;
        }
    
        memset(&addr,0,sizeof(SOCKADDR_IN));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(PORT);
        addr.sin_addr.s_addr=ADDR_ANY;
    
        rc=bind(acceptsocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
    
        if(rc == SOCKET_ERROR)
        {
            cout << "[ERROR]Bind fehler." << endl;
            system("PAUSE");
        } else{
            cout << "[INFO]Server würde an port [" << PORT << "] gebunden." << endl;
        }
    
        rc=listen(acceptsocket,1);
        if(rc == SOCKET_ERROR)
        {
            cout << "[ERROR]Listen error." << endl;
            system("PAUSE");
        } else
        {
            cout << "[INFO]Server im listen modus." << endl;
            cout << "[Server]-->Waiting for connections:" << endl << endl;
        }
    
        connectedsocket = accept(acceptsocket,(SOCKADDR*)&clientinfo,&clientinfolen);
        if(connectedsocket == INVALID_SOCKET)
        {
            cout << "[ERROR]Accept error." << endl;
            system("PAUSE");
        } else
        {
            cout << "[JOIN][" << inet_ntoa(clientinfo.sin_addr) << "][" << ntohs(clientinfo.sin_port) << "]"<< endl;
        }
    
        //SOCKET a = socket(AF_INET,SOCK_STREAM,0);
    
        char buffer[50];
    
        //...
    
        //CreateThread(0,0,(LPTHREAD_START_ROUTINE)dllfunction,0,0,0);
        CreateThread(0,0,(LPTHREAD_START_ROUTINE)schicken,&connectedsocket,0,0);
        //enviar(connectedsocket);
    
        while(1)
        {
            rc = recv(connectedsocket,buffer,50,0);
            if(rc == SOCKET_ERROR)
            {
                cout << "[LEAVE][" << inet_ntoa(clientinfo.sin_addr) << "][" << ntohs(clientinfo.sin_port) << "]" << endl;
                break;
            } else
            {
                buffer[rc]='\0';
                cout << "From client [" << inet_ntoa(clientinfo.sin_addr) << "]: "<< buffer << endl;
    
            }
        }
    
        return 0;
    }
    

    CLIENT:

    //CLIENT
    
    #include <iostream>
    #include <winsock2.h>
    #include <windows.h>
    #include <string>
    #include "Client.hpp"
    
    #define PORT 12345
    #define IP "127.0.0.1"
    
    char sendbuffer[50];
    char recvbuffer[50];
    
    using namespace std;
    
    long rc;
    
    void empfangen(SOCKET sock)
    {
        while(1)
        {
            Sleep(10);
            if(recv(sock,recvbuffer,50,0) == SOCKET_ERROR)
            {
                cout << "[ERROR]->Verbindung unterbrochen."<< WSAGetLastError() << endl;
                break;
            } else
            {
                cout << "From server: " << recvbuffer << endl;
            }
        }
    }
    
    void startwinsock()
    {
        WSADATA wsa;
        rc = WSAStartup(MAKEWORD(2,0),&wsa);
        if(rc != 0)
        {
            cout << "[ERROR]Winsock könnte nicht gestarted werden." << endl;
            system("PAUSE");
        } else {
    
            cout << "[INFO]Winsock würde gestarted." << endl;
        }
    }
    
    int main()
    {
        cout << "[INFO]Client wird gestarted." << endl;
        startwinsock();
    
        SOCKET s = socket(AF_INET,SOCK_STREAM,0);
    
        if(s == INVALID_SOCKET)
        {
            cout << "[ERROR]Socket könnte nicht erstellt werden." << endl;
            system("PAUSE");
        } else{
    
            cout << "[INFO]Socket würde erstellt." << endl;
        }
    
         SOCKADDR_IN addr;
    
         memset(&addr,0,sizeof(SOCKADDR_IN));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(PORT);
        addr.sin_addr.s_addr=inet_addr(IP);
    
        while(1)
        {
            Sleep(1000);
            if(connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)) == SOCKET_ERROR)
            {
                cout << "[ERROR]-->CONNECT GESCHEITERT." << endl;
            } else
            {
                cout << "[INFO]Verbunden mit server." << endl;
                break;
            }
        }
    
        //CreateThread(0,0,(LPTHREAD_START_ROUTINE)dllfunction,0,0,0);
        CreateThread(0,0,(LPTHREAD_START_ROUTINE)empfangen,&s,0,0);
        string input;
    
        while(1)
        {
            Sleep(10);
            std::getline(std::cin, input);;
            strcpy(sendbuffer,input.c_str());
            rc = send(s,sendbuffer,input.length(),0);
            if (rc == SOCKET_ERROR)
            {
                cout << "[ERROR]Send fehler." << endl;
            } else
            {
                cout << "[INFO]You send: " << input << endl;
        }
        }
        return 0;
    }
    

    Messages vom client zum server schicken klappt nur kann der server keine schicken da kommt "[ERROR]Send fehler.10038"

    Bei msdn steht:

    Socket operation on nonsocket.
    Ein Vorgang bezog sich auf ein Objekt, das kein Socket ist. Entweder hat der Sockethandleparameter nicht auf einen gültigen Socket verwiesen, oder für select war ein Member einer fd_set-Struktur nicht gültig.

    Also mein socket ist doch ein richtiger socket oder?? 😕



  • Habs nicht ausprobiert aber ich glaube dein erstellen des Threads ist fehlerhaft:

    CreateThread(0,0,(LPTHREAD_START_ROUTINE)schicken,&connectedsocket,0,0);
    

    Hier übergibst du die Adresse auf deinen Socket aber deine Funktion akzeptiert direkt den Socket. Ändere mal die Funktion so, dass die Signatur passt und du dir den Cast zu (LPTHREAD_START_ROUTINE) sparen kannst.



  • Jetzt funktioniert habe es so geändert :
    SERVER:

    //empfangen funktion...
    DWORD WINAPI empfangen(LPVOID lpParam)
    {
        //int numberThread = (int)lpParam;
        SOCKET sock = (SOCKET)lpParam;
        while(1)
        {
            std::getline(std::cin, input);;
            strcpy(buffers,input.c_str());
            rc = send(sock,buffers,input.length(),0);
            if (rc == SOCKET_ERROR)
            {
                cout << "[ERROR]Send fehler."<< WSAGetLastError() << endl;
            } else
            {
                cout << "[INFO]You send: " << input;
        }
        }
    }
    
    //Und thread darauf
    
    DWORD  threadId;
        HANDLE threadHandle;
        threadHandle = CreateThread(NULL, 0, empfangen, (LPVOID)connectedsocket,    0,&threadId)
    


  • OK, aber was wenn sizeof(SOCKET) > sizeof(LPVOID) ? So wäre es besser:

    DWORD WINAPI empfangen(LPVOID lpParam)
    {
      SOCKET sock = *((SOCKET*)lpParam);
      // ...
    }
    
    threadHandle = CreateThread(NULL, 0, empfangen, &connectedsocket, 0, &threadId);
    

Log in to reply