SDL_net - problem with SDLNet_CheckSockets

I compiled the example programs tcpmultiserver and tcpmulticlient and they
work fine.

I then took the code from these two programs, made a few minor changes,
put it into my program, and somehow broke it. I’ve spent literally all day
trying to work out what it is I changed which made it stop working, but I
can’t.

What happens is:

  • I start a server with one copy of the program, and a client with another
  • I connect the client to the server
  • The client successfully opens the address of the server
  • The server successfully hears the client and adds its socket to its
    socket set

But the next time round the server’s program loop its call to
SDLNet_CheckSockets returns -1. SDLNet_GetError returns no meaningful
error, and perror says “Bad file descriptor”.

Meanwhile, the next time round the client’s loop its call to
SDLNet_CheckSockets returns 1 - despite the fact the server hasn’t
actually sent it any messages. When the client uses my GetMessage function
to receive the size of the message that is supposedly waiting:

Uint32 result = SDLNet_TCP_Recv(sock, &len, sizeof(len));

the values of len and result are both huge. Last time I ran it through a
debugger the value of len was 3.5 billion ish (after being swapped for
local byte order) and the value of result is even huger (about 4.3 billion).

I really can’t work out where the problem is, despite the fact that my
code is basically a copy of someone else’s which does work. Here’s a
couple of bits of code in case someone can spot an obvious error.
connectSock is the server socket if the copy of the program is a server,
or otherwise it is the connection to the server if the program is a client.

int JamesNet::CheckSockets()
{
int numReady = SDLNet_CheckSockets(sockSet, 0);

if (numReady == -1)
{
	char output[100];
		sprintf(output, "SDLNet_CheckSockets: %s", SDLNet_GetError());
	perror("SDLNet_CheckSockets - perror say");
	throw runtime_error(output);
}

return numReady;

}

void JamesNet::SUpdate() //server update
{
int numReady = CheckSockets();

if (!numReady)
	return;

if (SDLNet_SocketReady(connectSock))
{
	--numReady;

	clients.push_back(SDLNet_TCP_Accept(connectSock));
	ReallSockSet();
}
	
for(vector<Client>::iterator iter = clients.begin(); numReady && iter != clients.end(); ++iter)
{
	if (SDLNet_SocketReady(iter->sock))
	{
		string theMessage;
		
		GetMessage(iter->sock, theMessage);
		--numReady;
		
		switch <snip>
	}
}

return;

}

void JamesNet::CUpdate() //client update
{
int numReady = CheckSockets();

if (numReady && SDLNet_SocketReady(sock))
{
	string theMessage;
	GetMessage(connectSock, theMessage);
	
	switch <snip>
}

return;

}

void JamesNet::ReallSockSet()
{
if (sockSet)
SDLNet_FreeSocketSet(sockSet);

sockSet = SDLNet_AllocSocketSet(clients.size() + 1);

if (!sockSet)
{
	char output[100];
		sprintf(output, SDLNet_GetError());
	throw runtime_error(output);
}

if (SDLNet_TCP_AddSocket(sockSet, connectSock) == -1)
{
	char output[100];
		sprintf(output, SDLNet_GetError());
	throw runtime_error(output);
}

for (int i = 0; i != clients.size(); ++i)
{
	if (SDLNet_TCP_AddSocket(sockSet, clients[i].sock) == -1)
	{
		char output[100];
		sprintf(output, SDLNet_GetError());
		throw runtime_error(output);
	}
}

return;

}

Thanks,

James