Thread: send() and recv() functions

  1. #1
    Eager young mind
    Join Date
    Jun 2006
    Posts
    342

    send() and recv() functions

    hi all,
    I have written a simple program to transfer a file from my comp to a remote pc using send() and recv() procedures...But, I am facing problems while trying to send big files ( appproximately the number of chars is more than 1500)..The char count at the sending end is the actual number that I am interested in,( I am measuring the char count after the send call), the entire file is not being received..Can anyone tell me if :
    1> there is an inbuilt restriction on the size of files being transfered
    2> if any,how to counter this problem
    3> else, where can things be going wrong..
    please help

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > 1> there is an inbuilt restriction on the size of files being transfered
    Make a guess - how do you think all those large ISO's you download are transferred?

    > 2> if any,how to counter this problem
    The network fragments large packets into small packets, reassembly is your problem to solve.
    Assuming that recv() returns some constant value identical to the value you passed to send() at the other end is an ASSUMPTION on your part.
    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.

  3. #3
    Eager young mind
    Join Date
    Jun 2006
    Posts
    342

    reply to the prev message

    well,
    I am not using the datagram technique..Only in datagram, each packet is allowed to take a different path( As far as my knowledge goes) .So, in my scheme of things, all the packets must arrive in order..ok,tailking about packets, any idea how large thay may be?? As I said, I cant transfer files having more than 2000 chars in one go..

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    So you're using TCP rather than UDP then?

    Which basically guarantees that all the bytes will arrive in the order you send them, in fragments.

    Post some code.
    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.

  5. #5
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    TCP will still fragment. send() and recv() both take four things: Two of which are a buffer to be send/recv'd, and the length of that buffer, right? Here's the catch: send() might not send the entire buffer. recv() might not fill the entire buffer. Both functions return the amount they've send/recv'd... it's up to you to check that all is as it should be. Usually, people either send a number saying, "I'm going to send this much", or receive like crazy until they hit a certain character (newline, null, etc...)

    See this page: 4.6 send() and recv()
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  6. #6
    Eager young mind
    Join Date
    Jun 2006
    Posts
    342
    I think the problem is with the max capacity of each packet.. I will check that out.. Is there any way ,by which we can control the size of each packet.. I am trying to minimise the number of sends and recvs in my prog.. Also,if the size of the file is too large, I must take care how much is being sent each time I call the send().. just to send one file across

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    It's a bit like this
    Code:
    ssize_t sendLargeBuffer ( int s, const void *buf, size_t len,  int flags ) {
      const unsigned char *pbuf = buf;
      ssize_t result;
      while ( len > 0 && (result=send(s,pbuf,len,flags)) > 0 ) {
        /* how much did we send - advance the progress */
        pbuf += result;
        len  -= result;
      }
    }
    It just keeps working it's way through the buffer (of whatever size) until it reaches the end of the buffer, or fails for some other reason.


    > I am trying to minimise the number of sends and recvs in my prog
    Your program is not the final arbiter of how many packets actually get sent across the network, so you're really wasting your time trying.
    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.

  8. #8
    Eager young mind
    Join Date
    Jun 2006
    Posts
    342
    hi,
    thanks.. I had decided to send data in chunks of 1000 chars at a time before I saw ur post..I see youe method does help too..

  9. #9
    Registered User
    Join Date
    Jun 2006
    Posts
    7
    the maximum you can send in each packet is OS dependant called the MTU, this can be seen with ifconfig in unix environments, and i think winipcfg or ipconfig or something under windows. MTU describes the maximum payload a single packet can deliver, not including the udp, tcp, ip and ethernet or other headers. MTU can vary across networks too, so beware. Usually though, for lans, MTU is 1500, so you can transfer a little less than 1.5 KB per packet. so if you want to transfer a file larger than this, you have to make a buffer of size less than the MTU, fill it, and send it, and repeat until all is done, with some housekeeping along the way. Its a good idea to include a header of your own in the packets, listing the size of the packets, so that you can confirm you are receiving whole sized packets before you try to process them. thats optional in some basic cases though, but recommended for heavy hitting.

  10. #10
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    No. The point trying to be made in this thread is that if you write socket code like it is meant to be written, then your program won't give a damn about packet sizes. Nor does it need to - let the OS and the network decide what size packets should be - that's their job, so that you don't reinvent the wheel. Don't worry about TCP packet sizes. Your socket, afterall, is a "stream"... no packets, at least from your perspective as a programmer.

    Send files of (almost) any size is trivial once you understand this. A very basic approach, is to send the size of the file, then the file itself. The other size receives the size (which it knowns ahead of time is like, 4 bytes) and then recv()'s like crazy. Concept:
    Code:
    int SendInt(int sock, unsigned int i)
    {
    	char buf[4];
    
    	buf[0] = i >> 24 & 0xFF;
    	buf[1] = i >> 16 & 0xFF;
    	buf[2] = i >> 8 & 0xFF;
    	buf[3] = i & 0xFF;
    
    	return SendFull(sock, buf, 4);
    }
    
    int SendFull(int sock, void *buf, unsigned int size)
    {
       int sent = 0, send_ret;
    
       while(sent < size)
       {
    	   send_ret = send(sock, buf + sent, size - sent, 0);
    	   if(send_ret <= 0) return 1;
    	   sent += send_ret;
       }
    
       return 0;
    }
    
    int SendFile(int sock, FILE *fp)
    {
       int file_size, bytes_read, total_read = 0;
       char buf[1024];
    
       fseek(fp, 0, SEEK_END);
       file_size = ftell(fp);
       fseek(fp, 0, SEEK_SET);
    
       if(SendInt(sock, file_size))
       {
    	   fprintf(stderr, "Failed to send file size.\n");
    	   return 1;
       }
       while(total_read < file_size)
       {
          bytes_read = fread(buf, sizeof(char), 1024, fp);
          if(bytes_read == 0) break;
          if(SendFull(sock, buf, bytes_read)) break;
          total_read += bytes_read;
       }
       if(total_read < file_size)
       {
    	   fprintf(stderr, "Failed to read all of file.\n");
    	   return 1;
       }
       return 0;
    }
    I'll leave it up to you to write a receiving end and find any bugs. And the buffer in there could be half size, double size, the receiving end wouldn't know or care.
    SendFull() is the one you should really look at. (Only 13 lines) As long as the socket doesn't explode, it ensures the buffer is sent. Completely. How? It asks send() how much was actually transferred.
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. TCP/IP Sockets in C (problem with send() and recv(): how to loop them)
    By ferenczi in forum Networking/Device Communication
    Replies: 3
    Last Post: 11-18-2008, 07:38 AM
  2. send and recv are cpu intensive?
    By Rune Hunter in forum Networking/Device Communication
    Replies: 14
    Last Post: 09-04-2007, 09:24 AM
  3. send and recv
    By DeadManWalking in forum C Programming
    Replies: 1
    Last Post: 12-04-2005, 09:17 AM
  4. Using recv() and send()
    By Sam_bham in forum C Programming
    Replies: 3
    Last Post: 06-08-2004, 04:36 PM
  5. Replies: 2
    Last Post: 03-05-2002, 05:52 AM