C Programming

Sendfile 2 C Function

The sendfile() is a function that copies the data between the two file descriptors. The sendfile() function is more effective than the read(2) and write(2) functions because it copies the data within the kernel rather than sending the information to and from the local storage. If you want to send files to a TCP connection using the sendfile() but needs to transmit some header data before the data files, you can use the TCP CORK option defined in tcp(7) to reduce the number of packets and tune the performance. Here, we use this article’s sendfile() system call. Files may be delivered quickly using the UDP protocol and a basic client/server. The files are handled by encryption of XOR.
 

Syntax of the Sendfile Function in C Language

sendfile(int out_fd, int in_fd, off_t * offset ", size_t" " count" );

The in_fd, out_fd, off_t * offset and the size_t count arguments are required for the function to work. The complete details of these arguments are as follows:

The file descriptors “in fd” and “out fd” should be assigned for reading and writing, respectively. If the offset value is not NULL, it refers to a variable that holds the file offset which the sendfile() will begin reading the data from in fd. This variable will be updated to the bytes of the offset that comes after the last byte read when sendfile() returns. Sendfile() does not change the current file offset of in fd if the offset is not NULL; otherwise, the current file offset is modified to reflect the Bytes read in number from “in fd”. The count parameter specifies how many bytes should be copied between the file descriptors.

The bytes amount written to “fd” is reverted if the communication is successful. It’s worth noting that a successful call to sendfile() may result in a fewer bytes being written than required; the caller must be willing to retry the operation if there are any unsent bytes. Also, if there is an exception, if -1 is provided, and errno is suitably set.

Error of the Sendfile() Function in C Language

EAGAIN: Nonblocking the write should block since I/O is configured with the O NONBLOCK.

EBADF: Either the input or output file could not be accessed for reading or writing.

EFAULT: An incorrect address has been entered.

EINVAL: The descriptor is either invalid or locked, or a mmap(2)-like operation for “in fd” is not accessible.

When reading from “in fd”, EIO: Unspecified error.

ENOMEM: Unable to acquire from the “in fd” due to a lack of memory.

Example 1: Send the File from the Server-Side in C Language in Ubuntu 20.04

We demonstrate how to send the files from the server-side which is accepted by the client-side in the following example by using the sendfile system call:






We won’t go into the details about this code because we are only interested in the C programming language’s sendfile function system call which is used to transfer a file to our client-side code. Here, we included all the applicable header files in the header section and defined some macros directives. Then, after this, we created a function to clear the buffer and a function cipher for the encryption. Then comes to the int sendfile function to send the file.

The constructor is declared for the sendfile function where the file and the buffer are defined. The algorithm for sending the files to the client-side is performed. First, the filename is sent to the server. If the file is present, the server begins reading it and keeps sending a buffer full of data. Until the end of the file, the contents are encrypted.

Then, we have the driver code of the main function. Inside the main function section, we defined the variables and structural variables which are required. The send_file() function sends the data from the file associated with the open file handle over the connection associated with the socket.

We utilized the socket function and passed the applicable parameters to it. We performed the if-else condition to the socket method variable, “sockfd”. If the “sockfd” is lesser than the value 0, the printf is called and prints the statement of the file descriptor that is not received. Otherwise, the compilation is terminated by displaying the else statement. We again used the if-else condition where the bind method is invoked for binging purposes. The bind method contains the required parameters. If the bind method operation is equal to the zero value, the “Binded successfully” is printed. If it fails to achieve the condition, the statement “Binding failed” is displayed on the prompt screen.

The while loop is deployed for receiving the file name. While receiving the file name, the statement “waiting for the file name” is displayed. After that, the file name is received from the clear_buf(). Through the “fopen”, we read the file and print the message “File name received” along with the file name. If the file is NULL, the statement “file opened failed” is printed. Otherwise, the “file opened successfully” is executed. Within our next while loop, we performed the sendfile process and sent the file with the sendto system call. In the end, the file is closed.

After the compilation of the code, we successfully sent the file to the client-server by the sendfile system call.

Example 2: Send a File from the Client-Side in C Language in Ubuntu 20.04
As we have seen in the preceding instance, we successfully sent the file to the server code. In this instance, we receive the data from the file sent by the server.




Just come to the “recvFile” method where we receive the file by applying the specified algorithm. A signal from either a socket’s connection mode or connectionless mode must be received by the recvFile() method. Because it prevents the application from retrieving the address of the source of the incoming data, it’s usually used with linked sockets. The Buffers of the file are received until the end of the file is received. The data is then decrypted. After that, we have a driver code. Inside the main function, we operated to connect the rocket method and received the file.

These are the following statements printed upon receiving the files. We can read the content of the data from the specified file inside the client-server:

Conclusion

To make things easier for our users, this post reviewed all of the technical aspects of using the C sendfile() function in the socket programming. The process can be considerably speed up by using the sendfile. Other measures such as accurately establishing the socket parameters must be followed to ensure that the network transfer is as efficient as feasible. To make it possible, we tried to include the easy examples. As a result, anyone using C who needs help with the “sendfile()” function will find this data useful.

About the author

Omar Farooq

Hello Readers, I am Omar and I have been writing technical articles from last decade. You can check out my writing pieces.