Jump to content
  • Advertisement
Sign in to follow this  
DanielH

Multiple asynchronous socket problems!

This topic is 5464 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm working on my first game using sockets but isn't going as good as I could hope for. First I used non-blocking sockets with a sepperate thread handling socket-receiving for the client and in the server one thread for accepting connections and one for handling messages sent by the clients. It worked but I had a lot of crashes and strange disconnect behaviors i couldn't fix so I decided to switch to asynchronous sockets. But since then... 1. When I start the server and client on the same computer it works fine to connect, but when I connect to a server on another computer the server cannot find the user from the userlist using the socket as id. The socket is added to that list on FD_CONNECT, what could have gone wrong? 2. Sometimes when the winsock message handler gets the FD_READ message and tries to read from the socket it just returns WSAEWOULDBLOCK. How can that happen??? I thought it could be because the socket was sending right then, but even if I loop the receive until some other error the loop will never end. This nevere happens when I step throught the application slowly in a debugger. It also seams that some messages never reaches the server/client eg. when the user fires multiple times. 3. Why does WSAGETSELECTERROR sometimes returns that the connection is reset? Should't these kind of events be handled by FD_CLOSE? Sorry for many spelling mistakes but I hope you'll understand most of it =)

Share this post


Link to post
Share on other sites
Advertisement
I highly recommend Network Programming for Microsoft Windows, Second Edition by Anthony Jones and Jim Ohmund.

Kuphryn

Share this post


Link to post
Share on other sites
I've checked it out but still haven't solved my problem.

I've been coding a test program and it seams that my send/recv code is bugged.


void CSocket::SendData(char *message, unsigned long length)
{
if (status == 0)
return;

int bytes;
unsigned long messageSize = length;
int total_sent = 0;

messageSize = htonl(messageSize);

do
{
bytes = send(sock, (char *)&messageSize+total_sent, sizeof(messageSize)-total_sent, 0);
if (bytes == SOCKET_ERROR)
{
/*
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
// Sleep(750);
continue;
}
*/
MessageBox(NULL, "send() error", "Error", MB_OK);
return;
}
total_sent += bytes;
} while (total_sent < sizeof(messageSize));

messageSize = ntohl(messageSize);

total_sent = 0;

do
{
bytes = send(sock, message+total_sent, length-total_sent, 0);
if (bytes == SOCKET_ERROR)
{
/*
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
// Sleep(750);
continue;
}
*/
MessageBox(NULL, "send() error", "Error", MB_OK);
return;
}
total_sent += bytes;
} while (total_sent < (int) messageSize);
}

int CSocket::GetData(char* dest)
{
if (status == 0)
return 0;

int bytes;
unsigned int messageSize;
int total_recv = 0;

do
{
bytes = recv(sock, (char *)&messageSize+total_recv, sizeof(messageSize)-total_recv, 0);
if (bytes == SOCKET_ERROR)
{
/*
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
Sleep(750);
continue;
}
*/
MessageBox(NULL, "recv() error", "Error", MB_OK);
return 0;
}
if (bytes == 0) return 0;

total_recv += bytes;
} while (total_recv < sizeof(messageSize));

messageSize = ntohl(messageSize);

total_recv = 0;

do
{
bytes = recv(sock, (dest+total_recv), (messageSize-total_recv), 0);
if (bytes == SOCKET_ERROR)
{
/*
if (WSAGetLastError() == WSAEWOULDBLOCK)
{
Sleep(750);
continue;
}
*/
MessageBox(NULL, "recv() error", "Error", MB_OK);
return 0;
}

if (bytes == 0) return 0;

assert(total_recv != messageSize);
total_recv += bytes;
} while (total_recv < (int) messageSize);

return bytes;



I get lots of "recv() error" messages when I try to receive data on FD_READ messages.

Share this post


Link to post
Share on other sites
You probably should put the actual error number and error text in your dialog box, to get a clue as to what's happening. Without that, you're just guessing. _snprintf() is a decent way of quickly formatting text for errors (but make sure you check for overruns!)

Share this post


Link to post
Share on other sites
I havent tries that yet, but I suppose its the WSAEWOULDBLOCK error since when I un-comment the WSAEWUOULDBLOCK error-check the program gets stuck in a never-ending loop.

As far as I've understood WSAEWOULDBLOCK is returned when you are trying to recv() from a socket that has nothing new to receive. But I'm calling the CSocket::GetData(...) on FD_READ messages, so I cannot understand whats the problem... I'm not 100% on this, but I think when I send a message from the client to the server, the server first pop-up an error message and then receives the real message. So is the FD_READ sent 2 times of which one is wrong?

Now while writing this it suddenly appeared to me that this might be because I first send the message size and then the buffer. Is this is? So if i merged the data to one buffer this problem will be solved...?

Share this post


Link to post
Share on other sites
I've been testing a little now - changing some code. Instantly after using the recv() the server receives another FD_READ message but when the program tries to receive from the socket it returns 0 bytes. Doesn't 0 bytes mean the user disconnected? Is this normal behavior for async sockets (=I should just ignore 0 bytes received)?

Share this post


Link to post
Share on other sites
If the socket is non-blocking, it can return 0 bytes when you try to read. I don't know the async socket API well enough to know if it does something similar. Are you also setting your socket as non-blocking, perchance?

What if you just treat the WOULDBLOCK error as "everything's OK" and do nothing, just returning to your regular business? Will you get an infinite stream of FD_READ messages? If not, I'd just accept the getting of 0 bytes and be happy. If you get an endless stream of messages, then either you're reading the wrong socket, or you're using the API wrong (wild guess that's probably wrong: perhaps async sockets will treat a non-blocking socket as always readable, and always send FD_READ messsages?)

Share this post


Link to post
Share on other sites
Could anyone give me a clear answer if ignoring WSAEWOULDBLOCK and 0 messages is the proper way to handle it?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!