C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 07-19-2002, 06:37 AM   #1
Unregistered
Guest
 
Posts: n/a
socket question

A general sockets question. Is there a parameter(s) that I need to set in order for this code to execute without the need for the Sleep() function? Without the Sleep(), the server starts to miss messages.

Both the client and server are running on the same 2Ghz machine so I would think that the computer is plenty fast.

Client code:
Code:
for (x = 1 ; x < 99 ; x++)
{
   sprintf(buffer, "%ld", CLIENT_REC);
   strcpy(Client.FName, "Joe");
   strcpy(Client.LName, "Public");
   Client.Age = 21;
   memcpy(buffer+4, &Client, sizeof(Client));
   RecSize = sizeof(Client) + sizeof(CLIENT_REC);


   if (send(s, buffer, /*strlen(buffer)*/ RecSize, 0) == -1)
   {
      printf("Can't send message\n"); 
      sockEnd(); 
      return 3; 
   }	

Sleep(55);  /*any value less than this, the server starts missing them */
}
Server code:
Code:
do
{
	MsgLen = recv(sSocket, buffer, BUFLEN, 0);

	if (MsgLen <= 0)
	{
		break;
	}

	buffer[MsgLen] = '\0';
	strcat(msg,buffer);

	strncpy(message, buffer, 4);
	message[4] = '\0';

	MsgType = atol(message);

	switch(MsgType)
	{
     	    case CLIENT_REC:
		/* pull the client structure out of the buffer */
				memcpy(&Client, buffer+4, sizeof(Client));
		fprintf(fp, "%d: Client: [%s] [%s] [%d]\n", pid, Client.FName, Client.LName, Client.Age);
		break;
	   default:
		printf("Unknown Message Type\n");
		break;
	}

	memset(msg,0,MSG_SIZE); 
	memset(buffer,0,BUFLEN);

} while(1);
  Reply With Quote
Old 07-19-2002, 08:49 AM   #2
End Of Line
 
Hammer's Avatar
 
Join Date: Apr 2002
Posts: 6,240
Your problem is this:

- without the delay, the client program hammers messages down the socket at a high speed. The OS and TCP/IP stack can and will collate messages into single a single packet if two or more are received within a small time difference.
- the server performs a read on the socket and gets given whatever is available at the time, which might be more than one of your "records". It will only read upto the number of bytes you specify as the 3rd parm of the socket() call.
- The result is the read is probably reading more than one "record" without you realising, and is only treating it as one.

To prove the theory, here's some output from a modified version of your program. All I have given here is the number of bytes received from the read() call, when the client sends it's 98 records:
Code:
Server received 28 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 56 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 100 bytes
Server received 60 bytes
In this example the read buffer was set to 100. This is an example of the same thing, but with the buffer set to 1000 bytes length
Code:
Server received 28 bytes
Server received 1000 bytes
Server received 456 bytes
Server received 1000 bytes
Server received 260 bytes
As you can see there were only 5 read()'s needed to get all the data.
__________________
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
Hammer is offline   Reply With Quote
Old 07-19-2002, 10:06 AM   #3
Unregistered
Guest
 
Posts: n/a
Thanks Hammer, I can see that in the debugger now. Ok, now what is the solution (ie. how is it done on systems that MUST scale very high)?

A). send a small message that says the next message is the size of the record such as:

Lets say the client program just sent the value 1000 (which represents a client record).

/* all records are #defined as a long value */
/* this, in effect, is saying "the next message will be msgSize bytes" */
msgSize = recv(ss, buffer, sizeof(long), 0)

msgSize is 4 bytes (buffer has the value "1000")

if (msgSize > 0)
{
msgSize = atol(buffer);

/* read the client record */
msgSize = recv(ss, buffer, msgSize, 0)
}


or

B). Handle the packets within the server by concatinating the recv buffer with a "holding buffer" and picking off the "long (record type) value" and the sizeof the record sent.

or

C) ??
  Reply With Quote
Old 07-19-2002, 01:54 PM   #4
End Of Line
 
Hammer's Avatar
 
Join Date: Apr 2002
Posts: 6,240
I would stick a couple of bytes on the front of every record denoting its length. Then make the read buffer as big as you like, being able to cope with multiple records of varying length.

Once the read is successful, interogate the first two bytes to get the length, the move that many bytes out of the buffer to where ever you want. If there's still data in the buffer, it must be from the next record, so start this step over again. If you get to the end of a buffer half way through a record, you know that you're going to get the rest of it on the next read (unless it disconnects for some reason), so you must concatenate the next read with this one.

This is just one method... you can choose to ignore this if you want.
__________________
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
Hammer is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Socket Question BENCHMARKMAN C Programming 15 03-12-2008 09:57 PM
Socket program mhetfield C Programming 5 04-03-2007 03:46 PM
Slight problem with socket reading!!! bobthebullet990 C Programming 5 02-15-2006 09:55 AM
problem closing socket Wisefool Networking/Device Communication 2 10-29-2003 12:19 PM
Simple Socket Question SourceCode Linux Programming 2 06-22-2003 09:20 PM


All times are GMT -6. The time now is 08:10 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