![]() |
| | #1 |
| Registered User Join Date: Apr 2004
Posts: 21
| FD_READ occasional data going missing.. 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;
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 | |
| | #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 | |
| | #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 | |
| | #4 |
| and the hat of Jobseeking 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. |
| Salem is offline | |
| | #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 | |
| | #6 |
| and the hat of Jobseeking 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! |
| Salem is offline | |
| | #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 | |
| | #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 | |
| | #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 | |
| | #10 |
| and the hat of Jobseeking 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. |
| Salem is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
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 |