Bardo91
Bardo91

Reputation: 585

c++ UDP socket error 10045

SOLVED

The error was assuming that UDP and TCP have same structure of connection and initialization. Here I get more information about it:

http://bit.kuas.edu.tw/~csshieh/teach/np/winsock/

Hope it helps to everyone in my situation

Question

Im trying to code a library that uses UDP socket. Previously I used TCP IP socket and I wrote them successfully, afterward I decided to templatize these one to generalize it.

To make secure the templatization I created a enum

enum eSocketType { eTCP = SOCK_STREAM, eUDP = SOCK_DGRAM };

Socket are created with a static member on socket class that is templatized and receive that kind of enum.

Templated socket works with eTCP. But when I used eDCP the bind process fail and I get the error 10045 that means that "The operation is not supported" as sais in MSDN support

The attempted operation is not supported for the type of object referenced. Usually this occurs when a socket descriptor to a socket that cannot support this operation is trying to accept a connection on a datagram socket.

SIMPLIFIED POST

Here is the summarize of the initialization code (It's the initialization proccess of the class that I described before editing the post (That is after "OLD POST" subsection)):

    int iResult = getaddrinfo(NULL, mPort.c_str(), &mHints, &mResult);
    if ( iResult != 0 ) {
        exit(-1);
    }
    mSocketOwn = socket(mResult->ai_family, mResult->ai_socktype, mResult->ai_protocol);
    if (mSocketOwn == INVALID_SOCKET) {
        freeaddrinfo(mResult);
        exit(-1);
    }

    #ifdef __linux__
        int yes = 1;
        iResult = setsockopt(mSocketOwn, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    #endif
    #ifdef _WIN32
        bool bOptVal = TRUE;
        int bOptLen = sizeof(bool);
        iResult = setsockopt(mSocketOwn, SOL_SOCKET, SO_REUSEADDR, (char *) bOptVal, bOptLen);
    #endif

    iResult = bind( mSocketOwn, mResult->ai_addr, mResult->ai_addrlen); // <-- Here fails
    if (iResult == SOCKET_ERROR) {
        // Here I get the error 10045 if a read the last error
        closeSocket();
        exit(-1);

    }
    freeaddrinfo(mResult);

OLD POST

Before copy/pasting the code here is the structure:

There is a Socket class that has virtual members and protected constructor. This class also has the static members that create ServerSocket and ClientSocket classes respectively. The static members have the fist level of template with the previous enum. ServerSocket and ClientSocket inherite from Socket and are templatized (because the initialization depend on that template). Hope this intro make the code more understandable... Here we go:

Socket interface:

class Socket{
        public:
            int sendData(std::string _data);
            std::string receiveData();

        protected:      
            Socket()    {};
            virtual int initializeSocket() = 0;
            virtual int connectSocket() = 0;

            virtual int closeSocket() = 0;

            int getLastError();

        public:     // static members: Factory, etc
            template<eSocketType type_>
            static ClientSocket<type_>* createClientSocket(std::string _ip, std::string _port);

            template<eSocketType type_>
            static ServerSocket<type_>* createServerSocket(std::string _port);

        protected:  
            #if defined(_WIN32)
                WSADATA mWsaData;
            #endif

            SOCKET mSocketOut;

            addrinfo *mResult, mHints;
        };  //  class Socket

ServerSocket Interface:

template

class ServerSocket: public Socket{
        public:
            ServerSocket(const std::string _port);

            int listenClient();
            SOCKET acceptClient();

        protected:
            int initializeSocket();
            int connectSocket();

            int closeSocket();

        private:
            SOCKET mSocketOwn;

            std::string mPort;
        };  //  class ServerSocket

I omitted the client because the error start creating the server. Basically the ServerSocket constructor call both method InitiallizeSocket and ConnectSocket that are here:

template<eSocketType type_>
int ServerSocket<type_>::initializeSocket(){
    // Resolve the server address and port
    std::cout << "Getting address info";
    int iResult = getaddrinfo(NULL, mPort.c_str(), &mHints, &mResult);
    if ( iResult != 0 ) {
        std::cout << "getaddrinfo failed with error: " << iResult << std::endl;
        #if defined (_WIN32)
            WSACleanup();
        #endif
        return 1;
    }
    std::cout << "----> Got address info" << std::endl;

    // Create a SOCKET for connecting to server
    std::cout << "Creating server socket";
    mSocketOwn = socket(mResult->ai_family, mResult->ai_socktype, mResult->ai_protocol);
    if (mSocketOwn == INVALID_SOCKET) {
        std::cout << "Socket failed. Error was: " << getLastError() << std::endl;
        freeaddrinfo(mResult);
        return 1;
    }
    std::cout << "----> Socket created" << std::endl;

    return 0;
}
//-----------------------------------------------------------------------------
template<eSocketType type_>
int ServerSocket<type_>::connectSocket(){
    // Setup the TCP listening socket
    int iResult = 0;
    #ifdef __linux__
        int yes = 1;
        iResult = setsockopt(mSocketOwn, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    #endif
    #ifdef _WIN32
        bool bOptVal = TRUE;
        int bOptLen = sizeof(bool);
        iResult = setsockopt(mSocketOwn, SOL_SOCKET, SO_REUSEADDR, (char *) bOptVal, bOptLen);
    #endif

    std::cout << "Binding to port";
    iResult = bind( mSocketOwn, mResult->ai_addr, mResult->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        std::cout << "Bind failed" << std::endl;
        std::cout << "Error was: " << getLastError() << std::endl;
        freeaddrinfo(mResult);
        closeSocket();
        return 1;
    }
    std::cout << "----> Binded to port" << std::endl;

    freeaddrinfo(mResult);
    return 0;

}

The socket is right initiallized but in the connectSocket method when it tries to bind it it fails and the 10045 error rises. As I said the TCP/IP socket work fine and no error rises. I read some tutorials about UDP socket but cant find any "missed step"... Does anyone know what is going on?

Thanks in advance, If more info is needed please tell me and I will add it. Pablo R.S.

Upvotes: 3

Views: 5457

Answers (2)

user207421
user207421

Reputation: 311050

It seems more likely that you were calling listen() on the UDP socket and getting the error from that. I don't see anything in this code that would cause that error on bind().

Upvotes: 2

Bardo91
Bardo91

Reputation: 585

The error was assuming that UDP and TCP have same structure of connection and initialization. Here I get more information about it:

http://bit.kuas.edu.tw/~csshieh/teach/np/winsock/

Hope it helps to everyone in my situation

Upvotes: 1

Related Questions