Reputation: 3877
I'm trying to build a server in C++ which can accept multiple number of clients. For that purpose I built a winsock wrapper and using threading with boost for communication for each clients.
I encountered a strange problem when trying to accept clients, I have a loop that looks like this.
int clientID = 0;
listenSocket = new Socket(SocketType::TCP);
listenSocket->Bind(port);
listenSocket->Listen();
while(running)
{
Socket *socket = &listenSocket->Accept();
mutex.lock();
clients.push_back(new Client(socket, clientID));
mutex.unlock();
std::cout << "Client with id " << clientID << " connected!" << std::endl;
std::cout << WSAGetLastError() << std::endl;
clientID++;
}
Now, the first client accepts fine and the WSAGetLastError() returns 0, but after the first one connected, even if I dont trying to connect another it just keep writing in the console 10093, which means the Accept() in the loop stoppped blocking and for some reason wont accept properly. I read online that this error caused by not calling WSAStartup() but I did called it in the socket's constructor and it did accept in the first time.
Upvotes: 5
Views: 32791
Reputation: 597971
10093 is WSANOTINITIALISED
, which means that either:
a socket call is being made before WSAStartup()
has been called at all.
a socket call is being made after WSACleanup()
has been called as many times as WSAStartup()
was called.
Based on the code you have provided, it appears that Socket::Accept()
is returning a Socket
object by value instead of a Socket*
pointer. If so, then Accept()
is creating a temporary Socket
that goes out of scope immediately after Socket *socket
is assigned. Chances are that the Socket
destructor is calling WSACleanup()
when it should not be. Calls to WSAStartup()
and WSACleanup()
must be balanced at all times.
The best time to call WSAStartup()
is during program startup, not inside in an object's constructor. And likewise, the best time to call WSACleanup()
is during program cleanup before exit, not inside of an object's destructor.
Upvotes: 18
Reputation: 1386
I was having the exact same problem while programming a cross platform socket application. It was working fine on linux and OS X but I was getting this error 10093 on windows. To fix it add this code before calling any of the winsock functions:
#ifdef WIN32
// Initialize Winsock
int iResult;
WSADATA wsaData;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
std::cout << "WSAStartup failed: " << iResult << std::endl;
return;
}
#endif
Upvotes: 13