简体   繁体   English

c ++ UDP套接字错误10045

[英]c++ UDP socket error 10045

SOLVED 解决了

The error was assuming that UDP and TCP have same structure of connection and initialization. 错误是假设UDP和TCP具有相同的连接和初始化结构。 Here I get more information about it: 在这里,我获得了更多相关信息:

http://bit.kuas.edu.tw/~csshieh/teach/np/winsock/ 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. 我试图编写一个使用UDP套接字的库。 Previously I used TCP IP socket and I wrote them successfully, afterward I decided to templatize these one to generalize it. 以前我使用TCP IP套接字并且我成功地编写了它们,之后我决定将这些文件模板化以概括它。

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. 模板化套接字与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 但是,当我使用eDCP时,绑定过程失败,我得到错误10045,这意味着“不支持该操作”作为MSDN支持中的 sais

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)): 以下是初始化代码的总结(这是我在编辑帖子之前描述的类的初始化过程(在“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);

OLD POST 旧帖子

Before copy/pasting the code here is the structure: 在复制/粘贴之前,这里的代码是结构:

There is a Socket class that has virtual members and protected constructor. 有一个Socket类,它有虚拟成员和受保护的构造函数。 This class also has the static members that create ServerSocket and ClientSocket classes respectively. 该类还具有分别创建ServerSocket和ClientSocket类的静态成员。 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). ServerSocket和ClientSocket继承自Socket并被模板化(因为初始化依赖于该模板)。 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: ServerSocket接口:

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: 基本上,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;

}

The socket is right initiallized but in the connectSocket method when it tries to bind it it fails and the 10045 error rises. 套接字是初始化的,但是当它尝试绑定它时在connectSocket方法中它失败并且10045错误上升。 As I said the TCP/IP socket work fine and no error rises. 正如我所说,TCP / IP套接字工作正常,没有错误上升。 I read some tutorials about UDP socket but cant find any "missed step"... Does anyone know what is going on? 我阅读了一些关于UDP套接字的教程,但是找不到任何“错过的步骤”......有谁知道发生了什么?

Thanks in advance, If more info is needed please tell me and I will add it. 在此先感谢,如果需要更多信息,请告诉我,我会添加它。 Pablo RS 巴勃罗RS

It seems more likely that you were calling listen() on the UDP socket and getting the error from that. 你似乎更有可能在UDP套接字上调用listen()并从中获取错误。 I don't see anything in this code that would cause that error on bind(). 我在这段代码中没有看到任何会导致bind()错误的内容。

The error was assuming that UDP and TCP have same structure of connection and initialization. 错误是假设UDP和TCP具有相同的连接和初始化结构。 Here I get more information about it: 在这里,我获得了更多相关信息:

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

Hope it helps to everyone in my situation 希望在我的情况下对每个人都有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM