Thread: File Reading/Writing Problems [Socket Programming]

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    45

    File Reading/Writing Problems [Socket Programming]

    Hello!

    First off I'm new here so sorry if my posts arn't so good. Second I'm from Belgian so sorry for my english!


    1. Are there any alternatives to fread and fwrite that doesn't require you specifing a buffer size? That directy write output/input
    2. Receiving files
      Code:
          FILE *fp;
          fp=fopen("c:\\filereceive.zip", "wb");
      
          int numbytes=0;
          int count =0;
          do {
              numbytes = recv(sockfd, buffer, sizeof(buffer), 0);
      
      
              count = count + numbytes;
      
              if (count >= 33801216 )
              {
                  closesocket(sockfd);
                  fclose(fp);
              }
              else
              {
                  fwrite(buffer, sizeof(buffer), 1, fp);
      
              }
          
          }while(numbytes > 0);
      • I receive the file but I don't know how to close it, the file is always corrupt.
      • I don't know how to send a file transfer complete to the sender; so what happends is that he keeps sending & the connection stays open.

    Main Problems:

    • Binary files are corrupted when receiving
    • Binary files smaller then the buffer size are corrupted
    • Can't send file completed over DCC


    THank you to any who can help me!
    -Ricky-

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    First off you shouldn't be writing sizeof(buffer) you should be writing numbytes after receiving a packet. The packet might be shorter than the buffer, so if you write the whole thing it will get corrupted.

    Second... 33,801,216 is going to overflow a 32bit integer so depending on the type of the variable count, you will get errors. count probably needs to be an unsigned long long int (uint64_t) for your code to work.

    Third the loop should not exit on numbytes = 0 ... if your sender is working properly every block of the file will be a full buffer long and only the last block will be shorter so you want to exit your loop when numbytes < buffersize.

    Finally you don't want a preset size to close the file and you don't want it inside your loop. The signal to close the file should be that the loop has exited.

    In pseudocode...
    Code:
    ** sender **
    unsigned char buffer[1024];
    open the file
    repeat
      read buffersize bytes into buffer
      send buffer
      if bytes read < buffersize
        exit loop
    close file
    
    
    ** receiver **
    unsigned char buffer[1024];
    open the file
    repeat
        bytes = receive up to buffersize bytes into buffer
        write(bytes) of  buffer to disk
        if bytes < buffersize 
          exit loop
    close file
    Last edited by CommonTater; 11-16-2011 at 08:23 AM.

  3. #3
    Registered User
    Join Date
    Nov 2011
    Posts
    45
    Quote Originally Posted by CommonTater View Post
    First off you shouldn't be writing sizeof(buffer) you should be writing numbytes after receiving a packet. The packet might be shorter than the buffer, so if you write the whole thing it will get corrupted.

    Third the loop should not exit on numbytes = 0 ... if your sender is working properly every block of the file will be a full buffer long and only the last block will be shorter so you want to exit your loop when numbytes < buffersize.
    With buffersize do you mean sizeof(buffer) so 1024? Because when I do it like this:

    Code:
        do {
            //Receiving From Socket
            numbytes = recv(sockfd, buffer, sizeof(buffer), 0);
    
            //Counting Bytes Received
            count = count + numbytes;
        /*    if (count >= filesize)
            {
                printf("\n:>File receive Completed\n");
                closesocket(sockfd);
                fclose(fp);
            }
            else
            {*/
                if (bolRecvFile == false)
                {
                    printf(":>Receiving file\n");
                    bolRecvFile = true;
                }
                fwrite(buffer, numbytes, 1, fp);
            //}
    
        }while(numbytes < 1024);

    This code works:
    Code:
        do {
            //Receiving From Socket
            numbytes = recv(sockfd, buffer, sizeof(buffer), 0);
    
            //Counting Bytes Received
            count = count + numbytes;
        /*    if (count >= filesize)
            {
                printf("\n:>File receive Completed\n");
                closesocket(sockfd);
                fclose(fp);
            }
            else
            {*/
                if (bolRecvFile == false)
                {
                    printf(":>Receiving file\n");
                    bolRecvFile = true;
                }
                fwrite(buffer, numbytes, 1, fp);
            //}
    
        }while(count < filesize);
    
        if (count >= filesize)
        {
            printf("\n:>File receive Completed\n");
            closesocket(sockfd);
            fclose(fp);
        }
    Last edited by MaSSaSLaYeR; 11-17-2011 at 06:23 AM.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Glad to see it working... but you should not count on sizeof() to return the number of characters in the buffer... it can also return the the size of the pointer to the buffer (usually 4).

    Code:
    #define BUFSIZE 1024
    
    unsigned char buffer[BUFSIZE];
    
    // other stuff
    
    numbytes = recv(sockfd, buffer, BUFFSIZE, 0);
    Also, are you explicitly communicating filesize before the transfer begins?
    If not, you should be exiting as I said...
    Code:
    do
      {
          receive and write
       }
    while (numbytes == BUFFERSIZE);
    This format is actually better since it will receive files of unknown size and will terminate the loop on errors.

  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
    > while (numbytes == BUFFERSIZE)
    recv() can return any number of bytes from 1 to the number you requested, and it still counts as success.

    You can't assume that recv() will hang around indefinitely until the buffer is full.

    Regardless of how many calls to send() there were, the number of recv() calls which result is completely independent (for a TCP stream). The only guarantee is the ORDER of the bytes. All fragmentation and reassembly is down to the user code.
    Code:
    do {
      n = recv(sockfd, buffer, BUFFSIZE, 0);
      if ( n == 0 ) {
        // remote closed connection
      } else if ( n < 0 ) {
        // an error
      } else {
        // do stuff with 'n' bytes
      }
    } while ( n > 0 );
    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
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Salem View Post
    > while (numbytes == BUFFERSIZE)
    recv() can return any number of bytes from 1 to the number you requested, and it still counts as success.
    [edit: I notice this is obliquely referred to in Salem's code, where "if n == 0"]

    Recv() can also return 0, and that sort of counts as success, since -1 is for error.

    At least on linux/GNU, this may happen when the other party disconnects. Ie, there is no error, SIGHUP, or SIGPIPE, but the connection will continuously trigger poll() or select() as ready to read, then the read will return 0.

    Ie, 0 is a crucial case to deal with. I don't close the connection until it happens a number of times in a row, but maybe that is paranoid since I have not noticed it happen for any other reason but a disconnection.
    Last edited by MK27; 11-17-2011 at 11:43 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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reading from and writing to same file
    By Strait in forum C++ Programming
    Replies: 2
    Last Post: 02-01-2005, 04:37 PM
  2. file writing and reading
    By Micko in forum C Programming
    Replies: 8
    Last Post: 01-13-2004, 11:18 AM
  3. Reading and Writing to a file
    By Granger9 in forum C Programming
    Replies: 0
    Last Post: 12-30-2002, 08:31 AM
  4. reading from the open socket then writing to a file...
    By Unregistered in forum C Programming
    Replies: 6
    Last Post: 07-06-2002, 04:15 PM
  5. writing a file to an open socket...
    By Unregistered in forum C Programming
    Replies: 9
    Last Post: 06-30-2002, 08:43 PM