c ++ UDP套接字错误10045

时间:2014-05-30 22:01:41

标签: c++ sockets udp

解决

错误是假设UDP和TCP具有相同的连接和初始化结构。在这里,我获得了更多相关信息:

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

希望在我的情况下对每个人都有帮助

问题

我试图编写一个使用UDP套接字的库。以前我使用TCP IP套接字并且我成功地编写了它们,之后我决定将这些文件模板化以概括它。

为了确保模板化的安全,我创建了一个枚举

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

使用套接字类上的静态成员创建套接字,该套接字被模板化并接收这种枚举。

模板化套接字与eTCP一起使用。但是当我使用eDCP时,绑定过程失败,我得到错误10045,这意味着“{3}}

中的sais不支持该操作”
  

对象类型不支持尝试的操作   引用。通常这发生在套接字的套接字描述符时   不能支持此操作的是尝试接受连接   数据报套接字。

简化发布

以下是初始化代码的总结(这是我在编辑帖子之前描述的类的初始化过程(在“OLD POST”小节之后)):

    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);

旧帖子

在复制/粘贴代码之前,这里的代码是结构:

有一个Socket类,它有虚拟成员和受保护的构造函数。该类还具有分别创建ServerSocket和ClientSocket类的静态成员。静态成员具有先前枚举的第一级模板。 ServerSocket和ClientSocket继承自Socket并被模板化(因为初始化依赖于该模板)。希望这个介绍能让代码更容易理解......我们走了:

套接字界面:

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接口:

模板

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

我省略了客户端,因为错误开始创建服务器。 基本上,ServerSocket构造函数调用这里的方法InitiallizeSocket和ConnectSocket:

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;

}

套接字是初始化的,但在connectSocket方法中,当它尝试绑定它时,它会失败并且10045错误会上升。 正如我所说,TCP / IP套接字工作正常,没有错误上升。我阅读了一些关于UDP套接字的教程,但无法找到任何“错过的步骤”......有谁知道发生了什么?

提前致谢,如果需要更多信息,请告诉我,我会添加它。 Pablo R.S。

2 个答案:

答案 0 :(得分:2)

您似乎更有可能在UDP套接字上调用listen()并从中获取错误。我在这段代码中看不到会在bind()上导致错误的任何内容。

答案 1 :(得分:1)

错误是假设UDP和TCP具有相同的连接和初始化结构。 在这里,我获得了更多相关信息:

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

希望在我的情况下对每个人都有帮助