C, sendfile() and send() difference?
c, linux, send, sendfile
Solution
If `fd` is a socket file descriptor, then these system calls are identical:
- `send(fd, data, length, 0)` is the same as `write(fd, data, length)`
- `recv(fd, data, length, 0)` is the same as `read(fd, data, length)`
So, unless you need to set a non-zero `flags` parameter, it makes no difference whether you use `send/recv` or `write/read`.
The `sendfile` system call is an optimization. If you have a socket `sockfd` and a regular file `filefd` and you want to copy some file data to the socket (e.g. if you're a web server serving up a file), then you might write it like this:
// Error checking omitted for expository purposes
while(not done)
{
char buffer[BUFSIZE];
int n = read(filefd, buffer, BUFSIZE);
send(sockfd, buffer, n, 0);
}
However, this is inefficient: this involves the kernel copying the file data into userspace (in the `read` call) and then copying the same data back into kernel space (in the `send` call).
The `sendfile` system call lets us skip all of that copying and have the kernel directly read the file data and send it on the socket in one fell swoop:
sendfile(sockfd, filefd, NULL, BUFSIZE);
Problem
sendfile() copies data between two file descripters within kernel space. Somewhere I saw if you are writing a web server in C in linux you should use send() and recv() instead of using write() and read(). So is the send() use the kernel space as well? Whatever I use for sending - sendfile() or send() - on the client side I'll be using recv() right? On the flip side, man page says: "The only difference between send() and write(2) is the presence of flags. With a zero flags argument, send() is equivalent to write(2)."