I need to write a simple file transfer protocol in C++ to upload or download a file from a client to a server. Right now both my client and server applications are do-it-all scripts. I want to modularize everything in classes/methods so I can more easily modify things later.
To upload a file, I need the name of user sending file (no authentication though), file name, file size, and file contents. This is what I have on client side:
int sendFile(string fileName, SOCKET s) {
ifstream file;
int ibytesent;
int size;
char fileSize[packetSize];
// Open file, set get pointer at end of file
file.open (fileName.c_str(), ios::binary | ios::ate);
// Get file size and pass it to buffer
size = (int) file.tellg();
//itoa(size, fileSize, packetSize);
sprintf(fileSize, "%d", size);
// Set pointer to beginning
file.seekg(0, ios::beg);
// Send file size
if (send(s, fileSize, packetSize, 0) == SOCKET_ERROR) {
throw "Send failed\n";
}
cout << "Size sent: " << size;
// Buffer the file Name
char fileNameBuffer[packetSize];
sprintf(fileNameBuffer, fileName.c_str());
// Send the file name
if (send(s, fileNameBuffer, packetSize, 0) == SOCKET_ERROR) {
throw "Send failed\n";
}
cout << "File name sent: " << fileName << endl;
char buf[packetSize];
ibytesent = 0;
// Loop until the whole file is sent
while(file.good()) {
// Read next packetSize bytes into buf
file.read(buf, packetSize);
// Send the read data
ibytesent += send(s, buf, packetSize, 0);
if (ibytessent == SOCKET_ERROR) {
throw "Send failed\n";
}
}
cout << "File sent.\n";
//wait for reception of server response.
ibytesrecv=0;
/*
if((ibytesrecv = recv(s,szbuffer,128,0)) == SOCKET_ERROR)
throw "Receive failed\n";
else
cout << "File received.";
*/
file.close();
return 1;
}
And then there is a main() method that opens up a socket and connects to the server. My question really is about how to design/implement a proper file transfer protocol. What is a good structure for it? I would also like to know your opinions about how to split (and send) a file into a packet structure rather than the way I do it now. I don't necessarily need code, but separation of concerns into this and that class, etc.
Please don't recommend an already existing protocol since that isn't the point of this exercise.
Thanks
EDIT I kind of found something similar to what I'm looking for here: http://www.eventhelix.com/realtimemantra/PatternCatalog/protocol_layer.htm