Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Try this code:</p> <p>Client side:</p> <pre><code>/* Client code */ /* TODO : Modify to meet your need */ #include &lt;stdio.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/socket.h&gt; #include &lt;stdlib.h&gt; #include &lt;errno.h&gt; #include &lt;string.h&gt; #include &lt;arpa/inet.h&gt; #include &lt;unistd.h&gt; #include &lt;netinet/in.h&gt; #define PORT_NUMBER 5000 #define SERVER_ADDRESS "192.168.1.7" #define FILENAME "/home/toc/foo.c" int main(int argc, char **argv) { int client_socket; ssize_t len; struct sockaddr_in remote_addr; char buffer[BUFSIZ]; int file_size; FILE *received_file; int remain_data = 0; /* Zeroing remote_addr struct */ memset(&amp;remote_addr, 0, sizeof(remote_addr)); /* Construct remote_addr struct */ remote_addr.sin_family = AF_INET; inet_pton(AF_INET, SERVER_ADDRESS, &amp;(remote_addr.sin_addr)); remote_addr.sin_port = htons(PORT_NUMBER); /* Create client socket */ client_socket = socket(AF_INET, SOCK_STREAM, 0); if (client_socket == -1) { fprintf(stderr, "Error creating socket --&gt; %s\n", strerror(errno)); exit(EXIT_FAILURE); } /* Connect to the server */ if (connect(client_socket, (struct sockaddr *)&amp;remote_addr, sizeof(struct sockaddr)) == -1) { fprintf(stderr, "Error on connect --&gt; %s\n", strerror(errno)); exit(EXIT_FAILURE); } /* Receiving file size */ recv(client_socket, buffer, BUFSIZ, 0); file_size = atoi(buffer); //fprintf(stdout, "\nFile size : %d\n", file_size); received_file = fopen(FILENAME, "w"); if (received_file == NULL) { fprintf(stderr, "Failed to open file foo --&gt; %s\n", strerror(errno)); exit(EXIT_FAILURE); } remain_data = file_size; while (((len = recv(client_socket, buffer, BUFSIZ, 0)) &gt; 0) &amp;&amp; (remain_data &gt; 0)) { fwrite(buffer, sizeof(char), len, received_file); remain_data -= len; fprintf(stdout, "Receive %d bytes and we hope :- %d bytes\n", len, remain_data); } fclose(received_file); close(client_socket); return 0; } </code></pre> <p>Server side:</p> <pre><code>/* Server code */ /* TODO : Modify to meet your need */ #include &lt;stdio.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/socket.h&gt; #include &lt;stdlib.h&gt; #include &lt;errno.h&gt; #include &lt;string.h&gt; #include &lt;arpa/inet.h&gt; #include &lt;unistd.h&gt; #include &lt;netinet/in.h&gt; #include &lt;sys/stat.h&gt; #include &lt;fcntl.h&gt; #include &lt;sys/sendfile.h&gt; #define PORT_NUMBER 5000 #define SERVER_ADDRESS "192.168.1.7" #define FILE_TO_SEND "hello.c" int main(int argc, char **argv) { int server_socket; int peer_socket; socklen_t sock_len; ssize_t len; struct sockaddr_in server_addr; struct sockaddr_in peer_addr; int fd; int sent_bytes = 0; char file_size[256]; struct stat file_stat; int offset; int remain_data; /* Create server socket */ server_socket = socket(AF_INET, SOCK_STREAM, 0); if (server_socket == -1) { fprintf(stderr, "Error creating socket --&gt; %s", strerror(errno)); exit(EXIT_FAILURE); } /* Zeroing server_addr struct */ memset(&amp;server_addr, 0, sizeof(server_addr)); /* Construct server_addr struct */ server_addr.sin_family = AF_INET; inet_pton(AF_INET, SERVER_ADDRESS, &amp;(server_addr.sin_addr)); server_addr.sin_port = htons(PORT_NUMBER); /* Bind */ if ((bind(server_socket, (struct sockaddr *)&amp;server_addr, sizeof(struct sockaddr))) == -1) { fprintf(stderr, "Error on bind --&gt; %s", strerror(errno)); exit(EXIT_FAILURE); } /* Listening to incoming connections */ if ((listen(server_socket, 5)) == -1) { fprintf(stderr, "Error on listen --&gt; %s", strerror(errno)); exit(EXIT_FAILURE); } fd = open(FILE_TO_SEND, O_RDONLY); if (fd == -1) { fprintf(stderr, "Error opening file --&gt; %s", strerror(errno)); exit(EXIT_FAILURE); } /* Get file stats */ if (fstat(fd, &amp;file_stat) &lt; 0) { fprintf(stderr, "Error fstat --&gt; %s", strerror(errno)); exit(EXIT_FAILURE); } fprintf(stdout, "File Size: \n%d bytes\n", file_stat.st_size); sock_len = sizeof(struct sockaddr_in); /* Accepting incoming peers */ peer_socket = accept(server_socket, (struct sockaddr *)&amp;peer_addr, &amp;sock_len); if (peer_socket == -1) { fprintf(stderr, "Error on accept --&gt; %s", strerror(errno)); exit(EXIT_FAILURE); } fprintf(stdout, "Accept peer --&gt; %s\n", inet_ntoa(peer_addr.sin_addr)); sprintf(file_size, "%d", file_stat.st_size); /* Sending file size */ len = send(peer_socket, file_size, sizeof(file_size), 0); if (len &lt; 0) { fprintf(stderr, "Error on sending greetings --&gt; %s", strerror(errno)); exit(EXIT_FAILURE); } fprintf(stdout, "Server sent %d bytes for the size\n", len); offset = 0; remain_data = file_stat.st_size; /* Sending file data */ while (((sent_bytes = sendfile(peer_socket, fd, &amp;offset, BUFSIZ)) &gt; 0) &amp;&amp; (remain_data &gt; 0)) { fprintf(stdout, "1. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, offset, remain_data); remain_data -= sent_bytes; fprintf(stdout, "2. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, offset, remain_data); } close(peer_socket); close(server_socket); return 0; } </code></pre> <p><strong>EDIT</strong> : Adding explanation from the man about the <code>offset</code></p> <p>The man page of send file said:</p> <blockquote> <p>If offset is not NULL, then it points to a variable holding the file offset from which sendfile() will start reading data from in_fd.<br> <strong>When sendfile() returns, this variable will be set to the offset of the byte following the last byte that was read</strong>.</p> </blockquote>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload