Reputation: 1297
I'm working on a client/server program where the client sends/receives files. The files may be text files or binary files. However, I am not sure what changes I need to make, if any, to accommodate for either file type. Basically I am looking to read/write to a file on the server side without caring what type of file it is, I would like to be able to do so without checking what type of file it was. Would code like this work? Why or why not?
Server snippet:
//CREATING/WRITING TO A FILE
//we are ready to begin reading data from the client, and storing it
int fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
while(nbytes < bytes)
{
//only read the neccessary # of bytes: the remaining bytes vs max buffer size
int min_buffer = (bytes - nbytes) < BUFFER_SIZE ? (bytes - nbytes) : BUFFER_SIZE;
length = recv( client->client_socket, contents, min_buffer, 0);
if(fd < 0) //the fd is bad, but we need to continue reading bytes anyway
{
nbytes += length;
continue;
}
if(length <= 0)
break;//string empty or error occurred...this error means the client closed?
if(write(fd, contents, min_buffer) != min_buffer)
{
//printf("There was an error writing to the file.\n");
}
else
{
nbytes += length;
}
}
//READING A STORED FILE AND SENDING THE DATA TO CLIENT
int fd = open(pathname, O_RDWR, S_IRUSR | S_IWUSR);
if(fd >= 0)
{
while(bytes > 0)
{
bytes = read(fd, buffer, BUFFER_SIZE );
if(bytes > 0)//we have read some bytes
{
//send the client the data
write(client->client_socket, buffer, bytes);
}
else if(bytes < 0)
{
//some error occured
write( client->client_socket, "ERROR: Could not read\n", 22);
return;
}
}
}
So if the client sends a binary file vs a text file, would this code cause issues? (We can assume the client knows what type of file to expect.)
Note: Another confusing detail about this is that there are tutorials for writing/reading binary files in c that didn't seem to have any real differences over regular files, which is what lead me here.
Upvotes: 3
Views: 4170
Reputation: 1
I tore my hair out for a day over a binary/text file issue. I was outputting binary data into "files" (apparently text files ... after years and years of C I'd always thought a file was a file) and kept getting spurious characters inserted into the output. I went so far as to download a new compiler but had the same problem. The issue? When I output hex A using any of the family of fprint statements, hex D was being inserted. Yes, line feed characters -- A -- were being replaced by carriage return/line feed -- DA. It's a legacy "end of line" issue based on how different systems have developed. The tough part of finding the problem was realizing A was being interpreted as more than just a binary field, but actually being recognized as a line feed.
Upvotes: -1
Reputation: 11434
Just do everything with "binary" files. Linux has no difference between "text" and "binary" in a file on OS level, there are just files with bytes in it. Ie. expect that a file contains every possible byte value, and don´t write different code for different kinds of content.
There is a difference in Windows: Text mode in Windows means that a line break (\n
) in the program gets converted to/from \r\n
when writing to / reading from a file. The written text file read in binary mode will contain this two bytes instead of the original \n
and vice-versa. (Additionally, MS isn´t very clear in the documentation that this is the only difference, it can confuse beginners easily.)
If you use standard C fopen
and fclose
instead of Linux-specific open
etc., you can specify to open a file in binary or text mode (on Linux too). This is because code with fopen should work on Windows and Linux without any OS-specific changes; but what you choose in fopen doesn´t matter when running on Linux (which can be verified by reading the source code of fopen etc.)
And about the sockets:
Linux: No difference (again)
Windows: No difference too. There are just bytes, and no strange line break conversions.
Upvotes: 11