diff --git a/headers/client.h b/headers/client.h index 0c81bf3af206682f3344a02eb129469ef2d5e54d..3523ef1fcd95137291140acf9d805ab98e80eb48 100644 --- a/headers/client.h +++ b/headers/client.h @@ -51,6 +51,7 @@ private: bool verify_ack(frame *received, frame *sent); frame *receive_ack(frame *f); vector<frame *> create_frames(vector<char> data, int type); + vector<frame *> create_frames_midia(vector<char> data); int send_frame_socket(frame *f); int start_transmission(); int end_transmission(); @@ -62,7 +63,7 @@ public: string userInput; // ------- Construtores ------ // - client(conexao *socketAddr) { socket = socketAddr; }; + client(conexao *socketAddr) { socket = socketAddr; } // ---------- Funcoes -------- // void run(); @@ -145,6 +146,8 @@ int client::end_transmission() { * @return int */ int client::send_frames(vector<frame *> frames) { + if (frames.empty()) { return 0; } + if (!start_transmission()) { return 0; } // Envia um frame por vez @@ -190,7 +193,16 @@ int client::send_message(vector<char> data, int type) { int messageSize = data.size(); vector<frame *> frames; - frames = create_frames(data, type); + + switch (type) { + case TEXTO: + frames = create_frames(data, type); + break; + + case MIDIA: + frames = create_frames_midia(data); + break; + } return send_frames(frames); } @@ -207,15 +219,12 @@ string client::calc_file_size(string fileName) { } vector<char> client::read_file(string fileName) { - fstream file; + ifstream file; file.open(fileName, ios::binary); - string teste; vector<char> fileData; - char c; - while ((file.get(c), file.eof() == false)) { - fileData.push_back(c); - } + for (char c; (file.read(&c, 1), file.eof()) == false; fileData.push_back(c)) + ; file.close(); return fileData; @@ -226,49 +235,23 @@ vector<char> client::read_file(string fileName) { * */ void client::send_file() { + vector<char> fileNameVector; string fileName; + do { - cout << "Digite o nome do arquivo(maximo de " << TAM_DADOS - 4 << " char):\n"; + cout << "Digite o nome do arquivo(maximo de " << TAM_DADOS + << " char):\n"; getline(cin, fileName); - } while (fileName.size() > TAM_DADOS - 4); + } while (fileName.size() > TAM_DADOS); - // Envia o primeiro frame com o tamanho do arquivo - string fileSize = calc_file_size(fileName); - if (fileSize.empty()) { return; } + fileNameVector.insert(fileNameVector.begin(), fileName.begin(), + fileName.end()); - cout << "Tamanho do arquivo: " << fileSize << "\n"; - cout << "Enviando tamanho do arquivo\n"; - if (!send_message(vector<char>(fileSize.begin(), fileSize.end()), MIDIA)) { - cout << "Limite de timout, arquivo nao foi enviado\n"; + if (!send_message(fileNameVector, MIDIA)) { + cout << "Falha ao enviar o arquivo\n"; return; } - // Envia o segundo frame com o nome do arquivo - cout << "Enviando nome do arquivo\n"; - string name = "NAME"; - vector<char>fileNameVector(name.begin(), name.end()); - fileNameVector.insert(fileNameVector.end(), fileName.begin(), fileName.end()); - - if (!send_message(fileNameVector, MIDIA)) - { - cout << "Limite de timout, arquivo nao foi enviado\n"; - return; - } - - cout << "Enviando arquivo\n"; - vector<char> file = read_file(fileName); - if ( file.empty() ) - { - cout << "Falha ao abrir o arquivo para leitura. Abortado\n"; - return; - } - - if (!send_message(file, DADOS)) - { - cout << "Limite de timout, arquivo nao foi enviado\n"; - return; - } - cout << "Arquivo enviado com sucesso\n"; } @@ -289,6 +272,43 @@ void client::send_text(string message) { cout << "Mensagem enviada com sucesso\n"; } +vector<frame *> client::create_frames_midia(vector<char> vectorName) { + vector<frame *> framesToSend; + vector<frame *> framesAux; + + // Cria um vetor com o tamanho do arquivo + vector<char> vectorTam; + string fileName = string(vectorName.begin(), vectorName.end()); + string fileSize = calc_file_size(fileName); + if (fileSize.empty()) { return vector<frame *>(); } + vectorTam.insert(vectorTam.begin(), fileSize.begin(), fileSize.end()); + + // Adiciona o tamanho no primeiro frame a ser enviado + framesAux = create_frames(vectorTam, MIDIA); + framesToSend.insert(framesToSend.end(), framesAux.begin(), framesAux.end()); + + // Adiciona o nome no segundo frame a ser enviado + framesAux = create_frames(vectorName, MIDIA); + framesToSend.insert(framesToSend.end(), framesAux.begin(), framesAux.end()); + + // Cria um vetor com os dados do arquivo + vector<char> vectorData = read_file(fileName); + if (vectorData.empty()) { + cout << "Falha ao abrir o arquivo para leitura\n"; + return vector<frame *>(); + } + + // Adiciona os dados do arquivo + framesAux = create_frames(vectorData, DADOS); + framesToSend.insert(framesToSend.end(), framesAux.begin(), framesAux.end()); + + // Arruma a sequencia dos frames + for (int i = 0; i < framesToSend.size(); i++) + framesToSend[i]->set_seq(i%16); + + return framesToSend; +} + /** * @brief Creates a vector with all the frames to be sent * @@ -337,8 +357,8 @@ void client::print_help() { cout << "Comandos disponiveis:\n"; cout << "help ou -h ou h ou HELP ou Help ou H ou ajuda ou Ajuda ou AJUDA\n"; cout << "exit ou -e ou e ou EXIT ou Exit ou E ou sair ou Sair ou SAIR\n"; - cout - << "send ou -s ou s ou SEND ou Send ou S ou enviar ou Enviar ou ENVIAR\n"; + cout << "send ou -s ou s ou SEND ou Send ou S ou enviar ou Enviar ou " + "ENVIAR\n"; cout << "para enviar uma mensagem, digite a mensagem e pressione enter\n"; } diff --git a/headers/server.h b/headers/server.h index 691cf5f97b1699737a8898cd1e5537c7f3b0cdfe..1316bea441c5fc7786e094e0efe6f187779f232d 100644 --- a/headers/server.h +++ b/headers/server.h @@ -52,6 +52,8 @@ private: bool create_received_dir(); string receive_file_name(); int receive_file_data(string fileName); + bool verify_crc8(frame *f); + bool verify_seq(int seq, int lastSeq); public: // ------- Construtores ------ // @@ -140,12 +142,33 @@ unsigned long server::chk_available_size() { // Recebe o frame com o tamanho do arquivo int server::receive_file_size(frame *f) { - if ( !strncmp(f->get_dado(), "NAME", 4)) { return 0; } + + /* + > verifica a sequencia do frame e o tipo + > se o frame nao for a sequencia esperada, envia um ack(0) e espera receber + a sequencia esperada > se o frame for o esperado, verifica o crc8 > se o + crc estiver certo, envia um ack e continua > se estiver errado, envia um + nack e espera receber o proximo frame + */ + do { + while (f->get_seq() != 1 && f->get_tipo() != MIDIA) { + f->set_seq(0); + send_ack(f); + f = receive_frame_socket(); + if (!f) { return 0; } + } + + if (verify_crc8(f)) { break; } + + // Se o ack nao estiver certo, espera receber o proximo frame + f = receive_frame_socket(); + if (!f) { return 0; } + } while (true); unsigned long availSize = chk_available_size(); if (availSize == -1) { return -1; } - cout << "frame file size:" << f->get_dado() << "\n"; + cout << "Frame file size:" << f->get_dado() << "\n"; int fileSize = stoi(f->get_dado()); if (fileSize > availSize * 0.9) { @@ -179,32 +202,50 @@ bool server::create_received_dir() { string server::receive_file_name() { frame *fReceive; - int lastSeq = -1; // Aguarda receber um frame do tipo midia com o nome do arquivo + // E com a sequencia de numero 2 + /* + > recebe o frame e verifica se o tipo e a sequencia estao corretos + > se estiverem, verifica o crc8 + > se estiver correto, envia um ack e continua + > se estiver errado, envia um nack e espera receber o proximo frame + */ do { - if (!receive_valid_frame(&fReceive)) { return string {}; } - if (fReceive->get_tipo() != MIDIA) { continue; } - if (strncmp(fReceive->get_dado(), "NAME", 4)) { continue; } + do { + fReceive = receive_frame_socket(); + if (!fReceive) { return string{}; } + + if (fReceive->get_tipo() != MIDIA) { continue; } + fReceive->set_seq(1); + send_ack(fReceive); + + } while (fReceive->get_seq() != 2); + if (verify_crc8(fReceive)) { break; } - if (fReceive->get_seq() == lastSeq) { continue; } - lastSeq = fReceive->get_seq(); + fReceive = receive_frame_socket(); + if (!fReceive) { return string{}; } - } while (fReceive->get_tipo() != FIMT); + } while (true); - cout << "Nome do arquivo recebido com sucesso\n"; - cout << "Nome do arquivo: " << fReceive->get_dado()+4 << "\n"; + cout << "Nome do arquivo: " << fReceive->get_dado() << "\n"; - return string(fReceive->get_dado()+4); + return string(fReceive->get_dado()); } -int server::receive_file_data(string fileName) { +bool server::verify_seq(int seq, int lastSeq) { + if (lastSeq == 15 && seq != 0) { return false; } + if (seq != lastSeq + 1) { return false; } + return true; +} +int server::receive_file_data(string fileName) { + cout << "\tRecebendo dados arquivo\n"; // Abre o arquivo para escrita ofstream file; - file.open(FILE_DESTINATION+"/"+fileName); + file.open(fileName, ios::binary); if (!file.is_open()) { cout << "Falha ao criar o arquivo. Abortado\n"; return 0; @@ -212,30 +253,45 @@ int server::receive_file_data(string fileName) { cout << "Arquivo criado com sucesso\n"; - int lastSeq = -1; + int lastSeq = 2; frame *f; do { - if (!receive_valid_frame(&f)) { return 0; } - if (f->get_tipo() != DADOS) { continue; } - if (f->get_seq() == lastSeq) { continue; } + // Fica tentando receber um frame + f = receive_frame_socket(); + if (f == NULL) { return 0; } + + if (f->get_tipo() == FIMT) { break; } + + if (f->get_tipo() != DADOS) { continue; } + + // Recebeu um frame com uma sequencia errada + if (!verify_seq(f->get_seq(), lastSeq)) { + f->set_seq(lastSeq); + send_ack(f); + continue; + } + + if (!verify_crc8(f)) { continue; } lastSeq = f->get_seq(); file.write(f->get_dado(), f->get_tam()); - } while (f->get_tipo() != FIMT); + + } while (true); cout << "Arquivo recebido com sucesso\n"; + file.close(); return 1; } void server::receive_midia(frame *f) { if (!create_received_dir()) { return; } - if (!receive_file_size(f)) { return; } + if (!receive_file_size(f)) { return; } string fileName = receive_file_name(); - if (fileName.size() == 0) { return; } + if (fileName.size() == 0) { return; } receive_file_data(fileName); } @@ -258,23 +314,27 @@ frame *server::receive_frame_socket() { return fReceive; } +bool server::verify_crc8(frame *f) { + int crc8 = f->chk_crc8(); + if (!crc8) { + send_nack(f); + } + else + send_ack(f); + return crc8; +} + int server::receive_valid_frame(frame **f) { - int crc8; do { // Se nao conseguir receber o frame, mata a comunicacao *f = receive_frame_socket(); if (*f == NULL) { return 0; } + cout << "Frame recebido loop\n"; + (*f)->imprime(HEX); // Avisa o cliente se nao conseguiu receber o frame - crc8 = (*f)->chk_crc8(); - if (crc8) { - send_ack(*f); - break; - } - send_nack(*f); - } while (!crc8); - + } while (!verify_crc8(*f)); return 1; } diff --git a/saida.txt b/saida.txt new file mode 100644 index 0000000000000000000000000000000000000000..1a56033fe38d2af10a0efb1223f107d4b1601fa8 Binary files /dev/null and b/saida.txt differ diff --git a/teste b/teste deleted file mode 100755 index 8b98f312be08825cee66554aeaa895ef0fff3670..0000000000000000000000000000000000000000 Binary files a/teste and /dev/null differ diff --git a/texto.txt b/texto.txt new file mode 100644 index 0000000000000000000000000000000000000000..4ae30933fdef6b3b0d4f30fcd64b0c5efc87d28c --- /dev/null +++ b/texto.txt @@ -0,0 +1,37 @@ + + + //string fileSize = calc_file_size(fileName); + //if (fileSize.empty()) { return; } + //franesFile.insert(framesFile.end(), fileSize.begin(), fileSize.end()); + + //cout << "Tamanho do arquivo: " << fileSize << "\n"; + //cout << "Enviando tamanho do arquivo\n"; + //if (!send_message(vector<char>(fileSize.begin(), fileSize.end()), MIDIA)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} + + // Envia o segundo frame com o nome do arquivo + //cout << "Enviando nome do arquivo\n"; + //string name = "NAME"; + //vector<char> fileNameVector(name.begin(), name.end()); + //fileNameVector.insert(fileNameVector.end(), fileName.begin(), fileName.end()); + + //if (!send_message(fileNameVector, MIDIA)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} + + //cout << "Enviando arquivo\n"; + //vector<char> file = read_file(fileName); + //if ( file.empty()) + //{ + // cout << "Falha ao abrir o arquivo para leitura\n"; + // return; + //} + + //if (!send_message(file, DADOS)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} +