In this article we explain how to implement client/server application where the server can send multiple files to client.
Introduction
Often on forums I come across on posts where people are interested how to implement different types of client/server applications. In this article, I will demostrate how one can implement a simple client/server application in C, where the server can send multiple files to the client (using TCP), and the client accepts these files. To run this code one should have Linux or Mac OSX environment.
Background
To perform network programming it is desirable that one understands basic networking concepts such as IP address, TCP, etc. In this article we will not go into details on explaining how to establish connection say using TCP between client and a server, since this topic is explored elsewhere. For elaborate explanation on the topic, reader is referred here: link. There is an article about this topic on Codeproject also: link. In any case this article includes a working sample code of a server and client implemented in C also which the reader can view in the downloads.
How to send files
In this project, the server sends multiple files to the client. There are two aspects related to this. First, the server sends the length of the file to the client. The client after receiving this length, knows how many bytes to expect from the server. This operation is repeated as many times as many files there are.
The second aspect is that the server sends the files in chunks. Meaning if the file is large, it is split, say in blocks of 256 bytes, and each block is sent like this. This is to avoid allocating too much space if the file is too big. The code for this, is presented below (notice this is code for sending the file in chunks on the server side, the client has a similar receiving function):
Collapse | Copy Code
/* Send given file over socket in chunks */
int send_file_in_chunks(int sockfd, char* filename, int size)
{
unsigned char buffer[300] = {0};
/* Open file which we want to send. */
FILE *ptr_myfile = fopen(filename,"rb");
if(!ptr_myfile)
{
return -1;
}
/* How many chunks are there? */
int div = size / 256;
/* Go through each chunk */
for(int k = 0; k < div; k++)
{
int chunk_size = 256;
/* Read chunk */
fread(buffer, 1, chunk_size, ptr_myfile);
/* Send it */
sendall(sockfd, buffer, &chunk_size);
}
/* Read final chunk and send it. */
int whatsleft = size - 256 * div;
fread(buffer, 1, whatsleft, ptr_myfile);
sendall(sockfd, buffer, &whatsleft);
return 0;
}
NOTE: Please note in the above function error checks are ommited for functions such as fread or sendall (e.g., we don't check their return values). The user should nonetheless put error checking there and handle errors appropriately. This maybe true also in other places of this project.
SendAll
The reader could have noticed in the above code that we use
sendall
method to send data to client. The thing is that ordinary send
method has one characteristic: even if you tell it to send say 50 bytes, it may not send 50 bytes, an send only 20. Sendall
method tries to avoid this problem, it will try to ensure that exactly 50 bytes (or as many as it is told to) are sent. Here is how implementation of sendall
method looks like (borrowed fromhere): Collapse | Copy Code
/* try to send given number of bytes over socket */
int sendall(int s, unsigned char *buf, int *len)
{
int total = 0;
int bytesleft = *len;
int n = 0;
while(total < *len)
{
n = send(s, buf + total, bytesleft, 0);
if(n == -1)
{
break;
}
total += n;
bytesleft -=n;
}
*len = total;
return (n == -1 ? -1 : 0);
}
Using the code
In the downloads section user can download a server source file and client source file separately. Both files include the standard code which involved creating sockets, performing binding, listening, accepting connections etc. which are also explained better in the links I provided. After this comes the implementation where the server sends 4 files to the client and client accepts this. Main parts of that code we have explained above. The client has similar methods though, like
receiveall
instead of sendall
and code for receiving file in chunks (we explained how to send file in chunks).Source from
http://www.codeproject.com/Tips/834154/Sending-multiple-files-from-server-to-client
No comments:
Post a Comment