Thread: how receive the large data using recv function in c++?

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    7

    Unhappy how receive the large data using recv function in c++?

    i developed client server program using c++,so i want to receive more than 1000000 bytes , my client message is terminated with "!" ,so i use loop in my server side but my server always wait for client data even client sent all data to the server ,this my server side recv() code.
    Code:
     do
         {
    
            iByteCount = recv(GetSocketId(), buffer,MAXRECV,0);
    
                    if ( iByteCount > 0 )
                    {
                        printf("Bytes received: %d\n",iByteCount);
                         strcat(buf,buffer);
                    }
                    else if ( iByteCount == 0 )
                    {
                           if(strlen(buf)>0)
                           {
                               //do process with received data
                           }
                           else
                          printf("receive failed");
                           break;
                    }
                    else
                        printf("recv failed: ");
                        break;
    
                } while(iByteCount > 0);
    }
    Last edited by mahi; 04-04-2012 at 06:07 AM.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    100
    I think we need more information. Which line is it waiting on? Can we see the definitions for recv(), GetSocketId(), iByteCount, and buf?

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    7
    actually i want to send 500kb data to server,when i sent that data means i cant get entire data it may divided into many packets so i want to receive all packets then only i will process my messsage ,that's the way i designed my code in this case i received all packet i cant process my message ,the control dsn't come out from while loop .

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Of course. Unless the socket is set non-block, recv() is a blocking call. Your condition is while(iByteCount > 0), but as long as the client stays connected and there are no errors, that will never happen*. This loop will just read everything the client sends, then keep waiting for more.

    You need to process the data as you receive it. That could mean just checking each chunk for ! until you find it then breaking out of the loop.

    * On linux, 0 will only happen if the client has disconnected, ie, the socket is defunct.
    Last edited by MK27; 04-04-2012 at 07:33 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The send and recv code should look something like this
    Code:
    // send
    char buff[10000];
    size_t len = strlen(buff);
    char *p = buff;
    ssize_t n;
    while ( len > 0 && (n=send(sock,p,len,0)) > 0 ) {
      p += n;
      len =- (size_t)n;
    }
    if ( len > 0 || n < 0 ) {
      // oops, something went wrong
    }
    
    
    // recv
    char buff[10000];
    size_t len = sizeof(buff);
    char *p = buff;
    ssize_t n;
    while ( len > 0 && (n=recv(sock,p,len,0)) > 0 ) {
      p += n;
      len =- (size_t)n;
    }
    if ( len > 0 || n < 0 ) {
      // oops, something went wrong
    }
    Note that BOTH ends use the return result to determine how much data was transferred, and then uses that result to update a buffer pointer and adjust the amount of data remaining.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Oct 2011
    Posts
    7
    ya.,thanks it's working fine .
    but there is another problem when sent/recv all data the loop will execute once and check (n & len value ) in this case that will be in -ve value after sent/ recv all data , so control goes to failed statement ,so how can i identify whether all data are sent and received?

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by MK27 View Post
    Of course. Unless the socket is set non-block, recv() is a blocking call. Your condition is while(iByteCount > 0), but as long as the client stays connected and there are no errors, that will never happen
    By "that will never happen" I meant the condition will never be untrue, lol, sorry for putting that badly.

    Quote Originally Posted by mahi View Post
    ya.,thanks it's working fine .
    but there is another problem when sent/recv all data the loop will execute once and check (n & len value ) in this case that will be in -ve value after sent/ recv all data , so control goes to failed statement ,so how can i ?
    This is a little confusing too, but it does not really matter exactly what you are trying to ask because no matter what:

    - the ONLY way you can "identify whether all data are sent" is to check the return value of send() until the appropriate number of bytes have been sent, as in Salem's example.

    - the ONLY way you can "identify whether all data are received" is to check the data. If the length of the data is predicable, you can do that by by checking the bytes received, the same way you do with send(); if the length of the data is not predictable, then you need to use some kind of protocol. Eg, you can use an "end of data" marker such as the ! you mentioned. Another way is to make the first four bytes an integer indicating the length of the remaining data, read that into a uint32_t, then read that many remaining bytes into your buffer.

    Other than that, there is no magical way for the receiver to know if it has received everything that was sent, which is why networking always involves protocols (in fact, layers of them; there is information transmitted under the hood your UDP socket, using the UDP protocol, which is why it is a UDP socket, but that information is of no use to you and thus inaccessible). Obviously enough: the only communication between the sender and receiver is what happens over the socket. That's all the information you have at your disposal.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Oct 2011
    Posts
    7
    but it tooks long time to recv all data ,another thing is i don;t know about the size of my data i am going to recv ,some time it may be 500 kb some time less than 10 kb how can i desined my code

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well one common way is to send the size of the data in advance of the data.

    For example, you could send a string reading
    "Sending 5 bytes of data\n"

    The receiver would read a line upto the first \n, then parse out 5 and then it would know how much data to expect.

    The sender would then send "hello", and the receiver would then receive 5 bytes of "hello" and conclude that the transmission was complete.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Oct 2011
    Posts
    7
    now i using this method ,it may better, thank you for your help.
    Code:
     char c;
    			    char temp[1024*1024];
    			    while (!found) {
    			        n = recv(GetSocketId(), &temp[total], sizeof(temp) - total - 1, 0);
    			        if (n == -1) {
    			        	 fprintf(stderr, "Error recv data %d\n", errno);
    			        	 return LS_RESULT_FAILED;
    
    			        }
    			        total += n;
    			        temp[total] = '\0';
    			        found = (strchr(temp, '!') != 0);
    			    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to receive data from serial port?
    By coolrox86 in forum C++ Programming
    Replies: 1
    Last Post: 04-23-2010, 03:04 PM
  2. How to Receive data from serial/USB port ?
    By sunit in forum C Programming
    Replies: 3
    Last Post: 06-19-2009, 12:16 PM
  3. recv large amounts of data
    By kpreston in forum Networking/Device Communication
    Replies: 19
    Last Post: 10-16-2008, 03:03 PM
  4. [Large file][Value too large for defined data type]
    By salsan in forum Linux Programming
    Replies: 11
    Last Post: 02-05-2008, 04:18 AM
  5. I want to avtivate modem to receive data
    By marquish in forum Networking/Device Communication
    Replies: 2
    Last Post: 07-21-2005, 12:01 AM

Tags for this Thread