Thread: File Writing Problem

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    2

    File Writing Problem

    So I'm writing a file transfer routine for two networked machines. I have a working version that has one machine read in the entire file into a buffer, and then transfer chunks over the network. However, I'd like to read in chunks from the file and send them as I go in case the file is very large. With that version, the file is transferred, it has the correct size, but no matter what file type it is, it will not open. For example, a .jpg throws an error saying "DNL not supported" or a text file has improper encoding.

    The code for the two version is very similar and I'm unable to figure out what the problem is. I believe the sendFile() function is where the problem is seeing as that is the function that differs in the two versions.

    Any help would be appreciated!

    Here is the working version that loads the entire file into memory:
    Code:
    void receiveFile(int sock, char* filename)
    {
    	FILE * pFile;
    	pFile = fopen(filename, "wb");
    
    	message msg;
    	void* buffer = (void*) &msg;
    	int rBytes, rv;
    	int pause;
    	
    	int finished = 0;
    	int bytesWritten = 0;
    	
    	while(!finished)
    	{
    		//ensure that we receive a complete msg object from the other end
    		for(rBytes = 0; rBytes < sizeof(msg); rBytes += rv)
    		{
    			if((rv = recv(sock, buffer+rBytes, sizeof(msg)-rBytes, 0)) < 0)
    				dieWithError("recv() failed");
    		}
    		
    		//convert size from network to host byte order
    		msg.size = ntohl(msg.size);
    		
    		//write the data we just received to the file
    		if(msg.size - bytesWritten < sizeof(msg.data))
    		{
    			fwrite(msg.data,1,msg.size - bytesWritten,pFile);
    			finished = 1;
    		}
    		else
    		{
    			fwrite(msg.data, 1, sizeof(msg.data), pFile);
    			bytesWritten += sizeof(msg.data);
    		} 
    	}
    	//close file
    	fclose (pFile);
    }
    
    void sendFile(int sock, char* filename)
    {
    	FILE* pFile;
    	long fileSize;
    	char* buffer;
    	size_t result;
    	
    	int copied;
    
    	pFile = fopen(filename,"rb");
    	if(pFile==NULL)
    		printf("error with fopen()");
    		
    	// obtain file size:
    	fseek(pFile, 0, SEEK_END);
    	fileSize = ftell(pFile);
    	fseek(pFile, 0, SEEK_SET);
    
    	// allocate memory to contain the whole file:
    	buffer = (char*)malloc(sizeof(char) * fileSize);
    	if(buffer == NULL)
    		printf("error with malloc()");
    
    	// copy the file into the buffer:
    	result = fread(buffer, 1, fileSize,pFile);
    	if(result != fileSize)
    		printf("error with fread()");
    
    	//the whole file is now loaded in the memory buffer.
    	
    	//send file to other client
    	message msg;
    	
    	copied = 0;
    	while(copied < fileSize)
    	{
    		memset(&msg, 0, sizeof(msg));
    		if(fileSize - copied < sizeof(msg.data))
    		{
    			memcpy(msg.data, buffer + copied, fileSize - copied);
    			copied += fileSize - copied;
    		}
    		else
    		{
    			memcpy(msg.data, buffer + copied, sizeof(msg.data));
    			copied += sizeof(msg.data);
    		} 
    		msg.size = htonl(fileSize);
    		send(sock, &msg, sizeof(msg), 0);
    	}
    
    	//close file
    	fclose(pFile);
    	free(buffer);
    }
    Here is the one that doesn't work. It uses the same corresponding receiveFile() function.
    Code:
    void sendFile(int sock, char* filename)
    {
    	FILE* pFile;
    	long fileSize;
    	char* buffer;
    	size_t readIn;
    	
    	int copied;
    
    	pFile = fopen(filename,"rb");
    	if(pFile==NULL)
    		printf("error with fopen()");
    		
    	// obtain file size:
    	fseek(pFile, 0, SEEK_END);
    	fileSize = ftell(pFile);
    	fseek(pFile, 0, SEEK_SET);
    	
    	//send file to other client
    	message msg;
    	copied = 0;
    	
    	while(copied < fileSize)
    	{
    		//allocate a buffer of appropriate size
    		if(fileSize - copied < sizeof(msg.data))
    			buffer = (char*)malloc((fileSize - copied) * sizeof(char));
    		else
    			buffer = (char*)malloc(sizeof(msg.data) * sizeof(char));
    		
    		//read in some data from the file
    		readIn = fread(buffer, 1, sizeof(buffer), pFile);
    		if(readIn != sizeof(buffer))
    			printf("error with fread()");
    		
    		//transfer the data into our message struct
    		memset(&msg, 0, sizeof(msg));
    		memcpy(msg.data, buffer, sizeof(buffer));
    		copied += sizeof(buffer);
    
    		msg.size = htonl(fileSize);
    		send(sock, &msg, sizeof(msg), 0);
    		free(buffer);
    	}
    
    	//close file
    	fclose(pFile);
    }

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    In your second sendFile() function, you're using sizeof(buffer), but that doesn't mean what it appears that you think it means.

    sizeof(buffer) tells you the size of the pointer, not the size of the allocated data: you have to remember that size yourself. Due to this, you're trying to read (probably) 4 bytes each time. Thus if the file size is not a multiple of 4 (or whatever the size of a pointer is), I would expect you to see the "error with fread()" message. Do you ever?

    At the very least, change the code to remove the use of sizeof(buffer); you can use a variable to store the amount of memory you allocate and use that instead. If I'm reading the code right, this should fix your problem. In receiveFile() you're assuming each chunk (save the last) is sizeof(msg.data) bytes long, and of course you're actually sending different-sized chunks.

  3. #3
    Registered User
    Join Date
    Feb 2009
    Posts
    2
    That was it. Thanks a bunch!

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > if((rv = recv(sock, buffer+rBytes, sizeof(msg)-rBytes, 0)) < 0)
    You should also use an unsigned char* for your buffer type.
    Relying on being able to add to a void* is not allowed.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with Creating File for File Processing
    By Dampecram in forum C Programming
    Replies: 2
    Last Post: 12-07-2008, 01:26 AM
  2. Problem with file writing
    By Goldrak in forum C++ Programming
    Replies: 7
    Last Post: 04-09-2006, 06:46 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM