socket question

This is a discussion on socket question within the C Programming forums, part of the General Programming Boards category; A general sockets question. Is there a parameter(s) that I need to set in order for this code to execute ...

  1. #1
    Unregistered
    Guest

    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);

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    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]

  3. #3
    Unregistered
    Guest
    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) ??

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    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]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Socket Question
    By BENCHMARKMAN in forum C Programming
    Replies: 15
    Last Post: 03-12-2008, 10:57 PM
  2. Socket program
    By mhetfield in forum C Programming
    Replies: 5
    Last Post: 04-03-2007, 04:46 PM
  3. Slight problem with socket reading!!!
    By bobthebullet990 in forum C Programming
    Replies: 5
    Last Post: 02-15-2006, 09:55 AM
  4. problem closing socket
    By Wisefool in forum Networking/Device Communication
    Replies: 2
    Last Post: 10-29-2003, 12:19 PM
  5. Simple Socket Question
    By SourceCode in forum Linux Programming
    Replies: 2
    Last Post: 06-22-2003, 10:20 PM

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