SOLVED
错误是假设UDP和TCP具有相同的连接和初始化结构 . 在这里,我获得了更多相关信息:
http://bit.kuas.edu.tw/~csshieh/teach/np/winsock/
希望在我的情况下对每个人都有帮助
Question
我试图编写一个使用UDP套接字的库 . 以前我使用TCP IP套接字并且我成功地编写了它们,之后我决定将这些文件模板化以概括它 .
为了确保模板化,我创建了一个枚举
enum eSocketType { eTCP = SOCK_STREAM, eUDP = SOCK_DGRAM };
套接字是在套接字类上使用静态成员创建的,它是模板化的并接收那种枚举 .
模板化套接字与eTCP一起使用 . 但是,当我使用eDCP时,绑定过程失败,我得到错误10045,这意味着"The operation is not supported" as sais in MSDN support
引用的对象类型不支持尝试的操作 . 通常,当对不能支持此操作的套接字的套接字描述符尝试接受数据报套接字上的连接时,会发生这种情况 .
SIMPLIFIED POST
以下是初始化代码的总结(这是我在编辑帖子之前描述的类的初始化过程(在“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
在复制/粘贴之前,这里的代码是结构:
有一个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 回答
你似乎更有可能在UDP套接字上调用listen()并从中获取错误 . 我在这段代码中没有看到任何会导致bind()错误的内容 .
错误是假设UDP和TCP具有相同的连接和初始化结构 . 在这里,我获得了更多相关信息:
http://bit.kuas.edu.tw/~csshieh/teach/np/winsock/
希望在我的情况下对每个人都有帮助