I'm writing a MUD server for personal learning purposes and I've, happily, managed to wrap up the socket stuff up into a couple of classes and everything appears to be working correctly; the server listens for and accepts connections and currently takes text from the client and sends it right back.
The thing is I'm not quite sure what to do with a call to accept() that returns something other than WSAEWOULDBLOCK or a valid socket. Do I just reset the new socket to 0 and return, with maybe an error message saying something bad happened? This is what I'm currently doing now, with the addition of if it happens 20 times I'll shut down the server.
void MUDControlSocket::Poll()
{
// create a new connection here
timeval timeout;
FD_ZERO(&ReadSet);
FD_ZERO(&WriteSet);
FD_ZERO(&ExceptionSet);
TopSocket = GetSocket();
NewSocket = 0;
FD_SET( GetSocket(), &ReadSet );
if( SocketList.size() > 0 )
{
for( sockIter iter = SocketList.begin(); iter != SocketList.end(); ++iter )
{
FD_SET((*iter)->GetSocket(), &ReadSet);
FD_SET((*iter)->GetSocket(), &WriteSet);
FD_SET((*iter)->GetSocket(), &ExceptionSet);
TopSocket = (*iter)->GetSocket();
}
}
if( select( TopSocket+1, &ReadSet, &WriteSet, &ExceptionSet, &timeout ) == SOCKET_ERROR )
{
cout << "Error on select() call: " << SocketErrorType(WSAGetLastError()) << endl;
delete this;
exit(EXIT_FAILURE);
}
// as long as everything is working correctly, this if block should always be entered UNLESS a new connection is accepted
if( (NewSocket = accept(GetSocket(), NULL, NULL) ) == INVALID_SOCKET )
{
if( WSAGetLastError() == WSAEWOULDBLOCK ) // it's not an actual problem. just nothing to connect to yet
return;
NewSocket = 0;
static int count = 0;
cout << "Error on accepting new connection: " << SocketErrorType(WSAGetLastError()) << endl;
if( ++count >= 20 )
done = true;
return;
}
SocketList.push_back(new MUDSocket(NewSocket)); // only happens if accept DOES NOT return a value of INVALID_SOCKET i.e. a new connection was accepted
TopSocket = NewSocket;
NewSocket = 0;
}
TopSocket and NewSocket are of type SOCKET and declared at file scope. SocketList is a std::list of MUDSocket* and MUDControlSocket is derived from MUDSocket as a singleton.
Let me know if you need more info and thanks for any help.