PDA

View Full Version : [TCP] Send to multiple clients


King Tokio
08-26-2009, 10:35 PM
So, with help from a few people here I managed to get my very basic client and server programs working. Many thanks!

I'm taking it up a step now by trying to send any message received by the server, back to all clients (excluding the sender).

My server send/recv code looks like this:
// Check all client sockets for activity
for (i = 0; i < SOCKETNUM; i++)
{
if (SDLNet_SocketReady(client[i].socket))
{
// There is an incoming message from the client
if (client[i].nameset == false)
{
SDLNet_TCP_Recv(client[i].socket, client[i].name,
sizeof(client[i].name));
cout << client[i].name << " connected.\n";
client[i].nameset = true;
}
else if (recvAll(client[i].socket, msg) == -1)
{
cout << client[i].name << " disconnected\n";
client[i].socket = NULL;
}
else
{
cout << client[i].name << ": " << msg << "\n";

len = (short)(strlen(msg)+1);
for (r = 0; r < SOCKETNUM; r++)
{
if (client[r].socket != NULL && r != i)
{
sendAll(client[r].socket, msg, len);
cout << "Sent: " << msg << "\n";
}
}
}
}
}

As you can see, the first message sent by the client is the username. All subsequent messages are printed and then sent back to all clients. I can't see anything wrong with this code, but when I run it and send some messages from the client, the server tells me it has sent a message back but no client receives anything.

This leads me to beleive it may be a client side error. Here is my client send/recv code:

// Get the message to send
cin.getline(msg, sizeof(msg));

len = (short)(strlen(msg)+1);
sendAll(sock, msg, len);

cout << "Sent: " << msg << "\nBytes: " << len << "\nEnter Message: ";

// Check for incoming message
if (SDLNet_SocketReady(sock))
{
if (recvAll(sock, msg) == -1)
{
cout << "You have been disconnected\n";
sock = NULL;
}
else
{
cout << "\nServer: " << msg << "\n";
}
}

Again I can see no coding error :( Oddly enough, the message IS sent back to all the clients, but only once in say, every 20 messages sent.

Anyone got any idea as to what might be wrong?

EDIT: None of the code within if(SDLNet_SocketReady(sock)){} is being executed which means the function call is probably returning false. But since the data IS being sent from the server, I don't know how this is possible.

alphadog
08-27-2009, 05:01 AM
http://docs.taoframework.com/Tao.Sdl/Tao.Sdl.SdlNet.SDLNet_SocketReady.html

"Check whether a socket has been marked as active. This function should only be used on a socket in a socket set, and that set has to have had SDLNet_CheckSockets (see SDLNet_CheckSockets) called upon it." (my emphasis)

King Tokio
08-27-2009, 07:10 AM
Thanks alphadog.

My server code creates an array of sockets and adds them to a socketset, but my client does not.

So I should be creating a socket set on the client and adding my single socket to it before making the call to SDLNet_SocketReady() ?

EDIT: I changed my code and I have it working sort of. However, the client is stopping at cin.getline() (obviously waiting for user input) and only receives one line of output from the server per loop, and only after the user has typed something.

Is there any way for me to accept user input without pausing the loop to wait for it?

alphadog
08-27-2009, 07:52 AM
Yes and have you read the API docs?

http://docs.taoframework.com/Tao.Sdl/Tao.Sdl.SdlNet.SDLNet_TCP_Recv.html
"If you read more than is sent from the other end, then it will wait until the full requested length is sent, or until the connection is closed from the other end. You may have to read 1 byte at a time for some applications..."

Many basic questions like yours are sometimes answered in the docs. Secondly, if you are going to write a client/server setup, it pays to read up on general socket principles, like blocking vs non-blocking and other things that can help you google the details on your particular SDK...

King Tokio
08-27-2009, 08:08 AM
Yes, I have read the docs (and docs such as "Beej's guide to network programming") from top to bottom. Not knowing that SDLNet_TCP_Recv() should only be used on a socket in a socket set was just a misassumption on my part.

My second error was just me forgetting how cin works (read: out of practice).

Maybe my second question was misleading. What I meant is that the client is not even calling SDLNet_TCP_Recv() until the user has entered a message and hit the return key. This is a problem with how I get input from the user, NOT with my network code. I wanted to know if there was a way to receive input from the user (not from the socket) without putting the loop on hold.

Again, thanks for your time and help :D