C Board  

Go Back   C Board > General Programming Boards > Networking/Device Communication

Reply
 
LinkBack Thread Tools Display Modes
Old 08-31-2004, 04:05 PM   #1
Registered User
 
Join Date: Apr 2004
Posts: 21
FD_READ occasional data going missing..

Hello all,

Maybe someone can shed some light on this problem for me as ive ran out of ideas here. I have a client/server style game and dont have any probs on the server side but the client side is giving me a little trouble of late...

The clients are Windows and im using Asyncronous Sockets to handle my data in coming in. When I get an Async notification I use a switch to determine the notification type.. its the read im having problems with :

Code:
case FD_READ:
  the_buf[0] = '\0';
  bytes_in = recv(s, the_buf, sizeof(the_buf), 0);
  if (bytes_in == 0)
  {
    MessageBox(DialogWindow, "Connection Closed","ERROR", MB_OK);
    break;
  }
  if (bytes_in == WSAEWOULDBLOCK) 
  {
    Sleep(750);
    bytes_in= recv(s, the_buf, sizeof(the_buf), 0); 
  }
  the_buf[bytes_in] = '\0';
  process(DialogWindow, the_buf, bytes_in);
break;
Ok now the odd thing is that this has worked fine for quite a while but someone from America connected to the server the other night (Server is in UK) and would on rare occasions "miss" bits of data being sent to them.

For example if there were 3 of us connecting we may get the messages :

Blah enters the room.
Blah does something.
Blah leaves the room.

Note those are 3 different messages sent by the server, however on this one occasions the person in america didnt get the message "Blah does something", it just didnt display. My suspicion was that the data came through too fast and therefore couldnt be handled quick enough so I added in the check for a WSAEWOULDBLOCK, if it would block I would wait 750ms and then try again.

This still however didnt cure the problem, doing quite abit of testing with this person it was very intermitant and didnt occur everytime and was in fact quite rare but it could be a major problem for me if the client needs to know something and its not being processed.

Sorry for the ramble but I wanted to make the setup clear before I asked for suggestions. Is my checking for WSAEWOULDBLOCK not sufficient enough to determine if the socket is OK for reading ?

Im also confusing myself alot at the operating system level.. When the data leaves the server by a send() function is it then held in a queue by the operating system which tries to send the client or if the send function cannot get the packet out would it simply discard it ? In terms of incoming, does the data come into an internal windows buffer of some kind which then sends my program the read notification ?

Apologies for the rather long post but if someone could clear this up for me or point me in the right direction id appreciate it.

Thanks

Stan
StanleyC is offline   Reply With Quote
Old 09-01-2004, 12:06 AM   #2
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 3,020
Well your error checking is actually incorrect. Give this a try:

Code:
case FD_READ:
  the_buf[0] = '\0';
  bytes_in = recv(s, the_buf, sizeof(the_buf), 0);
  if (bytes_in == 0)
  {
    MessageBox(DialogWindow, "Connection Closed","ERROR", MB_OK);
    break;
  }
  else if(bytes_in == SOCKET_ERROR)
  {
    int errorcode = GetLastError();
    if (errorcode == WSAEWOULDBLOCK) 
    {
      Sleep(750);
      bytes_in= recv(s, the_buf, sizeof(the_buf), 0); 
    }
  }
  else
  {
    the_buf[bytes_in] = '\0';
    process(DialogWindow, the_buf, bytes_in);
  }
break;
bithub is offline   Reply With Quote
Old 09-01-2004, 03:36 AM   #3
Registered User
 
Join Date: Apr 2004
Posts: 21
Thanks bithub, Ive adjusted my code to use the error checking correctly. Hopefully this will cure the problem.

Much appreciated.

Stan
StanleyC is offline   Reply With Quote
Old 09-01-2004, 12:50 PM   #4
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,693
> the_buf[0] = '\0';
This is pointless

> bytes_in = recv(s, the_buf, sizeof(the_buf), 0);
1. the_buf had better be an array (not a pointer), otherwise the sizeof will be not what you expect
2. you don't allow room to append a \0
bytes_in = recv(s, the_buf, sizeof(the_buf)-1, 0);

As your code stands, a full buffer will append the zero outside the array.


> Sleep(750);
No guarantee that waiting this long (or any other value) will result in a message being received.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 09-01-2004, 12:56 PM   #5
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 3,020
"As your code stands, a full buffer will append the zero outside the array."

That is wrong. recv() doesnt append a null terminator to the buffer! If it did, that would make receiving binary data rather cumbersome. The way he has it is correct.

Code:
char buff[128];
recv(s,buff,sizeof(buff),0);
bithub is offline   Reply With Quote
Old 09-01-2004, 01:06 PM   #6
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,693
> That is wrong.
I know recv() doesn't append a \0, the code which follows does that

char buff[5];
n = recv(s,buff, sizeof buff, 0 );
// if n == 5 here, then
buff[n] = '\0';
is a buffer overflow!
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 09-01-2004, 02:14 PM   #7
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 3,020
Yes, you are correct. I misunderstood what you meant in your earlier post.
bithub is offline   Reply With Quote
Old 09-05-2004, 03:42 PM   #8
Registered User
 
Join Date: Apr 2004
Posts: 21
Hi,

Thanks for the suggestions. Salem you mentioned in your post that :

No guarantee that waiting this long (or any other value) will result in a message being received.

You are correct as after doing some more testing ive started missing packets again on the clients when there is alot of activity on the server and its trying to send out data to the clients pretty fast.

Im stuck in identiying if the problems are with my sloppy network code on the client or on the server or if my network implementation is not working correctly. Ive even considered putting incoming messages into a queue system and actioning them each cycle rather than as and when they come in.

I know this is a very generalised question but has anyone any suggestions or procedures of what I could look into to figure out the best way to deal with fast incoming data? Any hints or tips regarding getting all the data in and trying to avoid the packet loss would be most appreciated.

Thanks

Stan
StanleyC is offline   Reply With Quote
Old 09-05-2004, 05:24 PM   #9
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 3,020
One option is to use regular blocking sockets in a different thread. Then you can use windows messages or some other mechanism to notify your main thread when data comes in. This removes the whole problem of having to worry about WSAEWOULDBLOCK.
bithub is offline   Reply With Quote
Old 09-06-2004, 02:22 AM   #10
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,693
Or just use select with a timeout to determine if there is anything to be read, then save yourself a whole bunch of complications which result from trying to synchronise threads.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Lame null append cause buffer to crash cmoo C Programming 8 12-29-2008 03:27 AM
Program Crashing Pressure C Programming 3 04-18-2005 10:28 PM
Binary Tree, couple questions scoobasean C Programming 3 03-12-2005 09:09 PM
Data missing in variable nizbit C Programming 8 03-07-2005 08:22 AM
odd errors from msvc std library files blight2c C++ Programming 6 04-30-2002 12:06 AM


All times are GMT -6. The time now is 05:19 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22