解决
错误是假设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。
答案 0 :(得分:2)
您似乎更有可能在UDP套接字上调用listen()并从中获取错误。我在这段代码中看不到会在bind()上导致错误的任何内容。
答案 1 :(得分:1)
错误是假设UDP和TCP具有相同的连接和初始化结构。 在这里,我获得了更多相关信息:
http://bit.kuas.edu.tw/~csshieh/teach/np/winsock/
希望在我的情况下对每个人都有帮助