/* * This function expects the sender to have already send a file message, * and when this function is running, continuosly send bytes until * fileSize bytes have been sent. */ bool ClientHandler::readFile(const std::string filename, size_t fileSize, Socket& socket, const std::string path) { std::string fqname = path + filename; FileSystem::File file(fqname); file.open(FileSystem::File::out, FileSystem::File::binary); if (!file.isGood()) return false; const size_t BlockSize = 2048; Socket::byte buffer[BlockSize]; size_t bytesToRead; while (true) { if (fileSize > BlockSize) bytesToRead = BlockSize; else bytesToRead = fileSize; socket.recv(bytesToRead, buffer); FileSystem::Block blk; for (size_t i = 0; i < bytesToRead; ++i) blk.push_back(buffer[i]); file.putBlock(blk); if (fileSize < BlockSize) break; fileSize -= BlockSize; } file.close(); return true; }
/* * - Sends a message to tell receiver a file is coming. * - Then sends a stream of bytes until the entire file * has been sent. * - Sends in binary mode which works for either text or binary. */ bool MsgClient::sendFile(const std::string& filename, Socket& socket) { // assumes that socket is connected std::string fqname = "../TestFiles/" + filename; FileSystem::FileInfo fi(fqname); size_t fileSize = fi.size(); std::string sizeString = Converter<size_t>::toString(fileSize); FileSystem::File file(fqname); file.open(FileSystem::File::in, FileSystem::File::binary); if (!file.isGood()) return false; HttpMessage msg = makeMessage(1, "", "localhost::8080"); msg.addAttribute(HttpMessage::Attribute("file", filename)); msg.addAttribute(HttpMessage::Attribute("content-length", sizeString)); sendMessage(msg, socket); const size_t BlockSize = 2048; Socket::byte buffer[BlockSize]; while (true) { FileSystem::Block blk = file.getBlock(BlockSize); if (blk.size() == 0) break; for (size_t i = 0; i < blk.size(); ++i) buffer[i] = blk[i]; socket.send(blk.size(), buffer); if (!file.isGood()) break; } file.close(); return true; }
// -------------- << Sends File via socket >> ----------------- bool Sender::sendFile(const std::string & filename, Socket & socket, int fPort, int tport) { std::string fqname = filename; FileSystem::FileInfo fi(fqname); size_t fileSize = fi.size(); std::string sizeString = Converter<size_t>::toString(fileSize); std::string toPort = Converter<int>::toString(tport); std::string fromPort = Converter<int>::toString(fPort); FileSystem::File file(fqname); file.open(FileSystem::File::in, FileSystem::File::binary); if (!file.isGood()) return false; HttpMessage msg = makeMessage(1, "", "localhost::"+toPort); msg.addAttribute(HttpMessage::Attribute("file", filename)); msg.addAttribute(HttpMessage::Attribute("content-length", sizeString)); msg.addAttribute(HttpMessage::Attribute("To-Port", toPort)); msg.addAttribute(HttpMessage::Attribute("From-Port", fromPort)); sendMessage(msg, socket); const size_t BlockSize = 2048; Socket::byte buffer[BlockSize]; while (true) { FileSystem::Block blk = file.getBlock(BlockSize); if (blk.size() == 0) break; for (size_t i = 0; i < blk.size(); ++i) buffer[i] = blk[i]; socket.send(blk.size(), buffer); if (!file.isGood()) break; } file.close(); return true; }
void MsgClient::downloadFile(const std::string& fqname, size_t fileSize, Socket& socket) { std::string path = "Download/" + fqname; FileSystem::File file(path); file.open(FileSystem::File::out, FileSystem::File::binary); if (!file.isGood()) { /* * This error handling is incomplete. The client will continue * to send bytes, but if the file can't be opened, then the server * doesn't gracefully collect and dump them as it should. That's * an exercise left for students. */ Show::write("\n\n can't open file " + fqname); } const size_t BlockSize = 2048; Socket::byte buffer[BlockSize]; size_t bytesToRead; while (true) { if (fileSize > BlockSize) bytesToRead = BlockSize; else bytesToRead = fileSize; socket.recv(bytesToRead, buffer); FileSystem::Block blk; for (size_t i = 0; i < bytesToRead; ++i) blk.push_back(buffer[i]); file.putBlock(blk); if (fileSize < BlockSize) break; fileSize -= BlockSize; } file.close(); }