I would like to implement a client-server architecture running on Linux using sockets and C/C++ language that is capable of sending and receiving files. Is there any library that makes this task easy? Could anyone please provide an example?
I would like to implement a client-server architecture running on Linux using sockets and
Share
The most portable solution is just to read the file in chunks, and then write the data out to the socket, in a loop (and likewise, the other way around when receiving the file). You allocate a buffer,
readinto that buffer, andwritefrom that buffer into your socket (you could also usesendandrecv, which are socket-specific ways of writing and reading data). The outline would look something like this:Make sure to read the documentation for
readandwritecarefully, especially when handling errors. Some of the error codes mean that you should just try again, for instance just looping again with acontinuestatement, while others mean something is broken and you need to stop.For sending the file to a socket, there is a system call,
sendfilethat does just what you want. It tells the kernel to send a file from one file descriptor to another, and then the kernel can take care of the rest. There is a caveat that the source file descriptor must supportmmap(as in, be an actual file, not a socket), and the destination must be a socket (so you can’t use it to copy files, or send data directly from one socket to another); it is designed to support the usage you describe, of sending a file to a socket. It doesn’t help with receiving the file, however; you would need to do the loop yourself for that. I cannot tell you why there is asendfilecall but no analogousrecvfile.Beware that
sendfileis Linux specific; it is not portable to other systems. Other systems frequently have their own version ofsendfile, but the exact interface may vary (FreeBSD, Mac OS X, Solaris).In Linux 2.6.17, the
splicesystem call was introduced, and as of 2.6.23 is used internally to implementsendfile.spliceis a more general purpose API thansendfile. For a good description ofspliceandtee, see the rather good explanation from Linus himself. He points out how usingspliceis basically just like the loop above, usingreadandwrite, except that the buffer is in the kernel, so the data doesn’t have to transferred between the kernel and user space, or may not even ever pass through the CPU (known as "zero-copy I/O").