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