diff --git a/headers/client.h b/headers/client.h index 05638ffe61d6c30f17ad31fe40453cdd7ddcc14e..33bfd99517145bd3e2756aa4354a1b96a18b80e0 100644 --- a/headers/client.h +++ b/headers/client.h @@ -8,7 +8,6 @@ #include <iostream> #include <linux/if.h> #include <linux/if_packet.h> -#include <mutex> #include <net/ethernet.h> #include <netinet/in.h> #include <stdio.h> @@ -23,6 +22,7 @@ #include "conexao.h" #include "cores.h" #include "frame.h" + using namespace std; class client { @@ -41,11 +41,11 @@ private: bool string_has(string str, vector<string> strList); char string_cmd(string str); void print_help(); - bool verify_ack(frame *received, frame *sent); - frame *receive_ack(frame *f); + bool verify_ack_nack(frame *received); + frame *receive_ack_nack(); vector<frame *> create_frames(vector<char> data, int type); vector<frame *> create_frames_midia(vector<char> data); - int send_frame_socket(frame *f); + frame *send_frame_socket(frame *f); int start_transmission(); int end_transmission(); string calc_file_size(string fileName); @@ -65,50 +65,53 @@ public: // ------------------------------ PRIVATE --------------------------------- // // Verifica se recebeu um ack valido -frame *client::receive_ack(frame *f) { - frame *ack_res = NULL; +frame *client::receive_ack_nack() { + frame *response = NULL; // se recebemos algo, e NÃO ẽ o ACK que estamos // esperando, continuamos tentando receber do { - ack_res = socket->receive_frame(); - if (ack_res && ack_res->get_tipo() == ERRO) { + response = socket->receive_frame(); + if (response && response->get_tipo() == ERRO) { cout << BOLDYELLOW << "Espaco insulficiente no destino\n" << RESET; return NULL; } - } while (ack_res && - !(verify_ack(ack_res, f) && ack_res->get_dado()[0] == f->get_seq())); + } while (response && !(verify_ack_nack(response))); - return ack_res; + return response; } // Solicita ao socket que envie um frame -int client::send_frame_socket(frame *f) { +frame *client::send_frame_socket(frame *f) { // Fica tentando enviar o frame até receber o ack - frame *ack_res = NULL; + frame *response = new frame(); int retries = 0; do { // envia um frame da fila - socket->send_frame(f); - ack_res = receive_ack(f); + int bytesSent = socket->send_frame(f); + if (bytesSent == -1) { return NULL; } + + response = receive_ack_nack(); + if (!response) return NULL; retries++; - } while (ack_res == NULL && retries < NUM_RETRIES); + } while (response->get_dado()[0] != f->get_seq() && retries < NUM_RETRIES); - if (ack_res == NULL && retries == NUM_RETRIES) { - // cout << "Desisti de enviar\n"; ->log - return 0; + if (response == NULL && retries == NUM_RETRIES) { + cout << "Desisti de enviar\n"; + return NULL; } - // cout << "\tACK recebido:\n"; ->log - // ack_res->imprime(HEX); - return 1; + cout << "\tACK recebido:\n"; + response->imprime(HEX); + return response; } // Inicia a transmissao com o servidor int client::start_transmission() { // cout<< YELLOW << "\tIniciando transmissao\n" << RESET; ->log frame *ini = new frame(INIT, 0, vector<char>(1, 0)); - int enviado = send_frame_socket(ini); + frame *enviado = new frame(); + enviado = send_frame_socket(ini); if (!enviado) { // cout<< BOLDRED << "\tFalha ao iniciar a transmissao\n" << RESET; ->log return 0; @@ -122,7 +125,7 @@ int client::start_transmission() { int client::end_transmission() { // cout << "\tEncerrando a transmissao\n"; ->log frame *end = new frame(FIMT, 0, vector<char>(1, 0)); - int enviado = send_frame_socket(end); + frame *enviado = send_frame_socket(end); if (!enviado) { // cout << "\tFalha ao encerrar a transmissao\n"; ->log return 0; @@ -139,23 +142,68 @@ int client::end_transmission() { * @return int */ int client::send_frames(vector<frame *> frames) { + if (frames.empty()) { return 0; } + cout << "\tstart transmission\n"; if (!start_transmission()) { return 0; } + cout << "\t ->>> started transmission <<< -\n"; - // Envia um frame por vez - for (size_t i = 0; i < frames.size(); i++) { + // Cria a fila de frames + queue<int> janela; + int frameCounter; + int iniJanela = 0; + while (iniJanela < frames.size()) { - // cout << "\tEnviando frame\n"; ->log - // frames[i]->imprime(DEC); + // manda todos os frames de uma vez só + for (frameCounter = 0; frameCounter < TAM_JANELA; frameCounter++) { + if (iniJanela + frameCounter == frames.size()) { break; } + janela.push(frameCounter); + + cout << "\tEnviando frame\n"; + frames[iniJanela]->imprime(HEX); + + if (socket->send_frame(frames[iniJanela + frameCounter]) == -1) { + cout << "Falha ao enviar o frame\n"; + return 0; + } + + cout << "\tFrame enviado com sucesso\n"; + } - int enviado = send_frame_socket(frames[i]); - if (!enviado) { - // cout << "\tFalha ao enviar o frame\n"; ->log - return 0; + // Recebe a resposta do servidor + for (int i = 0; i < min((int)TAM_JANELA, (int)frames.size()); i++) { + frame *res = NULL; + int retries = 0; + + do { + res = receive_ack_nack(); + retries++; + } while (res == NULL && retries < NUM_RETRIES); + + if (res == NULL && retries == NUM_RETRIES) { return 0; } + + if (res->get_tipo() == NACK && res->get_dado()[0] == janela.front()) { + cout << "NACK " << (int)res->get_dado()[0] << " recebido\n"; + iniJanela += res->get_dado()[0]; + janela.pop(); + break; + } + + if (res->get_tipo() == ACK && res->get_dado()[0] == janela.front()) { + cout << "ACK " << (int)res->get_dado()[0] << " recebido\n"; + iniJanela++; + janela.pop(); + } + + else { + i--; + } } - // cout << "\tFrame enviado com sucesso\n"; ->log + // apaga a janela + while (!janela.empty()) + janela.pop(); } if (!end_transmission()) { return 0; } @@ -172,8 +220,9 @@ int client::send_frames(vector<frame *> frames) { * @return true * @return false */ -bool client::verify_ack(frame *received, frame *sent) { - return (received->get_tipo() == ACK && received->chk_crc8()); +bool client::verify_ack_nack(frame *received) { + return ((received->get_tipo() == ACK || received->get_tipo() == NACK) && + received->chk_crc8()); } /** @@ -300,7 +349,7 @@ vector<frame *> client::create_frames_midia(vector<char> vectorName) { // Arruma a sequencia dos frames for (int i = 0; i < framesToSend.size(); i++) - framesToSend[i]->set_seq(i % 16); + framesToSend[i]->set_seq(i % TAM_JANELA); return framesToSend; } diff --git a/headers/conexao.h b/headers/conexao.h index 702e89f82e838a887b659cde9d2f0f2dfef873ab..2fcab792cefc8d421796b5278492c9df5abbe9a5 100644 --- a/headers/conexao.h +++ b/headers/conexao.h @@ -19,12 +19,12 @@ #include <arpa/inet.h> // include local -#include "frame.h" #include "cores.h" +#include "frame.h" using namespace std; -#define BYTE "%02x" -#define NUM_RETRIES 100 +#define NUM_RETRIES 10 +#define TAM_JANELA 2 class conexao { private: @@ -89,10 +89,6 @@ frame *conexao::receive_frame() { do { byteRecv = recv(device, bufferReceived, sizeof(frame) * 2, 0); - // for (int i = 0; i < byteRecv; i++) { - // cout << hex << (int(bufferReceived[i])&0xff) << " "; - // } - // cout << "\n"; if ((byteRecv > 0) && (bufferReceived[0] == INI)) { frame *f = new frame; remove_escapes(bufferReceived, (char *)f); @@ -116,12 +112,15 @@ int conexao::send_frame(frame *f) { int timeout = 0; int byteSend = send(device, bufferSend, sizeof(frame) * 2, 0); - // printf("send %d: ", byteSend); - // for (int i = 0; i < byteSend; i++) { - // cout << hex << (int(bufferSend[i]) & 0xff) << " "; - // } - // cout << "\n"; - // if (byteSend < 0) { cout << "Erro no sendto" << byteSend << "\n"; } ->log + printf("send %d: ", byteSend); + for (int i = 0; i < byteSend; i++) { + cout << hex << (int(bufferSend[i]) & 0xff) << " "; + } + cout << "\n"; + if (byteSend < 0) { + cout << "Erro no sendto" << byteSend << "\n"; + return -1; + } return byteSend; } @@ -166,7 +165,7 @@ int conexao::ConexaoRawSocket(char *device) { soquete = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); /*cria socket*/ if (soquete == -1) { - cout << BOLDRED <<"\tErro no Socket, verifique se voce eh root\n" << RESET; + cout << BOLDRED << "\tErro no Socket, verifique se voce eh root\n" << RESET; exit(-1); } diff --git a/headers/macros.h b/headers/macros.h index a936d2fd44134ddbf5398f985340968d5de3535f..57c4d1b865683cfea8b293c11ce6e34d8f292d04 100644 --- a/headers/macros.h +++ b/headers/macros.h @@ -3,6 +3,7 @@ #define UC unsigned char #define UI unsigned int +#define UL unsigned long // Macro que cria uma sequencia com o 1 deslocado "des" posicoes a direita #define MASKR(des) (1 << des) diff --git a/headers/server.h b/headers/server.h index 18a2854dcb8e99c34c769fcc5a32a12942b07528..09359aa1078628e02076e3b2b5fd0746c4422a14 100644 --- a/headers/server.h +++ b/headers/server.h @@ -21,9 +21,10 @@ #include <sys/types.h> // include local -#include "conexao.h" #include "cores.h" #include "frame.h" +#include "macros.h" +#include "conexao.h" #define FILE_DESTINATION "./received" @@ -33,28 +34,34 @@ class server { private: // --------- Dados ---------- // - int soquete; + //int soquete; + int tipoReceivingFrames; conexao *socket; - vector<frame *> framesMidia; + //vector<frame *> framesMidia; // ---------- Funcoes -------- // - int send_nack(frame *fReceive); - int send_ack(frame *fReceive); - void send_confirm(frame *fReceive); - void receive_text(frame *f); - void receive_midia(frame *f); + + frame* create_ack_nack (int tipo, int seq); + int send_nack (frame *fReceive); + int send_ack (frame *fReceive); + bool verify_seq (int seq, int lastSeq); + int next_tipo_midia (frame *f); + bool create_received_dir (); + UL chk_available_size (); + int receive_file_size (frame *f); + string create_file_destination(string fileName); + ofstream create_file (string fileName); + int receive_midia (frame *f); + //void send_confirm(frame *fReceive); + //void receive_text(frame *f); + //int receive_valid_frame(frame **f); + //int receive_file_data(string fileName); + //bool verify_crc8(frame *f); frame *receive_frame_socket(); - int receive_valid_frame(frame **f); - unsigned long chk_available_size(); - int receive_file_size(frame *f); + queue<frame *> receive_frames_window(int lastSeq); void start_receveing_message(); - 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 ------ // @@ -65,6 +72,27 @@ public: }; // ------------------------------ PRIVATE --------------------------------- // +/** + * @brief function that creates a nack or a nack + * + * @param tipo ack or nack + * @param seq ack or nack sequence number + * @return int + */ + +frame *server::create_ack_nack(int tipo, int seq) +{ + vector<char> seq_char; + frame *f = new frame(); + + f->set_tipo(tipo); + vector<char> seq_v; + seq_v.push_back(char(seq)); + f->set_dado(seq_v); + + return f; +} + /** * @brief function that sends a ack frame to the target * @@ -73,17 +101,16 @@ public: */ int server::send_ack(frame *fReceive) { - frame *ack = new frame(); + frame *ack = create_ack_nack(ACK, fReceive->get_seq()); - ack->set_tipo(ACK); - vector<char> seq; - seq.push_back(char(fReceive->get_seq())); - ack->set_dado(seq); - - int ackSent = 0; - ackSent = socket->send_frame(ack); + int ackSent = socket->send_frame(ack); + if ( ackSent == -1 ) + { + cout << "Falha ao enviar o ack\n"; + return -1; + } - // cout << "ACK enviado\n"; ->log + cout << "ACK " << (int) fReceive->get_seq() << " enviado\n"; return ackSent; } @@ -96,43 +123,68 @@ int server::send_ack(frame *fReceive) { */ int server::send_nack(frame *fReceive) { - frame *nack = new frame(); + frame *nack = create_ack_nack(NACK, fReceive->get_seq()); - nack->set_tipo(NACK); - vector<char> seq; - seq.push_back(char(fReceive->get_seq())); - nack->set_dado(seq); - - int nackSent = 0; - nackSent = socket->send_frame(nack); + int nackSent = socket->send_frame(nack); + if ( nackSent == -1 ) { + cout << "Falha ao enviar o nack"; + return -1; + } - // cout << "NACK enviado\n"; ->log + cout << "NACK " << (int) fReceive->get_seq() << " enviado\n"; return nackSent; } -// Recebe uma mensagem em forma de texto -void server::receive_text(frame *f) { - string textoReceive; - textoReceive.append(f->get_dado()); - int lastSeq = f->get_seq(); +/** + * @brief function that verify if two numbers are sequential + * + * @param seq + * @param lastSeq + * @return bool + */ +bool server::verify_seq(int seq, int lastSeq) { + if ( seq == 0 ) + { + if ( lastSeq != 15 ) { return false; } + return true; + } - do { - if (!receive_valid_frame(&f)) { return; } - if (f->get_tipo() != TEXTO) { continue; } - if (f->get_seq() == lastSeq) { continue; } + if (seq != lastSeq + 1) { return false; } + return true; +} - lastSeq = f->get_seq(); - textoReceive.append(f->get_dado()); - } while (f->get_tipo() != FIMT); +int server::next_tipo_midia(frame *f) { + if ( f->get_tipo() != MIDIA ) { return -1; } + if ( f->get_seq() == 0 ) { return MIDIA; } + if ( f->get_seq() == 1 ) { + cout << YELLOW << "\t--Recebendo dados arquivo--\n" << RESET; + return DADOS; } - cout << BOLDYELLOW << "\t--Mensagem recebida--\n " << BOLDWHITE - << textoReceive << "\n" - << RESET; + return -1; } -// Verifica o espaco disponivel em disco -unsigned long server::chk_available_size() { +//// Recebe uma mensagem em forma de texto +//void server::receive_text(frame *f) { +// string textoReceive; +// textoReceive.append(f->get_dado()); +// int lastSeq = f->get_seq(); +// +// do { +// if (!receive_valid_frame(&f)) { return; } +// if (f->get_tipo() != TEXTO) { continue; } +// if (f->get_seq() == lastSeq) { continue; } +// +// lastSeq = f->get_seq(); +// textoReceive.append(f->get_dado()); +// } while (f->get_tipo() != FIMT); +// +// cout << "Mensagem recebida: " << textoReceive << "\n"; +//} +// +//// Verifica o espaco disponivel em disco + +UL server::chk_available_size() { struct statvfs st; if (statvfs(FILE_DESTINATION, &st) == -1) { // cout << "Erro no statvfs, abortado\n";->log @@ -143,47 +195,22 @@ unsigned long server::chk_available_size() { return st.f_bsize * st.f_bavail; } -// Recebe o frame com o tamanho do arquivo +//// Recebe o frame com o tamanho do arquivo int server::receive_file_size(frame *f) { - /* - > 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 - */ - // cout << "Recebendo tamanho do frame\n";->log - do { - if (f->get_tipo() != MIDIA) { continue; } - if (f->get_seq() == 0 && verify_crc8(f)) { break; } - - if (f->get_seq() != 0) - cout << "Sequencia errada\n"; - else - cout << "Crc errado\n"; - - cout << "Aguardando frame\n"; - - f = receive_frame_socket(); - if (!f) { return 0; } + cout << "Recebendo tamanho do frame\n"; + unsigned long availSize = chk_available_size(); + if (availSize == -1) { return -1; } - cout << "Frame recebido\n"; + cout << "Frame file size:" << f->get_dado() << "\n"; + int fileSize = stoi(f->get_dado()); - } while (true); - - unsigned long availSize = chk_available_size(); - if (availSize == -1) { return -1; } - - // cout << "Frame file size:" << f->get_dado() << "\n"; ->log - int fileSize = stoi(f->get_dado()); - - if (fileSize > availSize * 0.9) { + if (fileSize > availSize * 0.9) { cout << BOLDMAGENTA << "\t--Tamanho do arquivo muito grande, abortado--\n" << RESET; // send_error(); return 0; - } + } // cout << "Espaco suficiente em disco\n"; ->log return 1; @@ -191,7 +218,8 @@ int server::receive_file_size(frame *f) { bool server::create_received_dir() { - // check if the directory exists + cout << "Criando diretorio"; + // Check if the directory exists struct stat info; if (stat(FILE_DESTINATION, &info) == 0 && (info.st_mode & S_IFDIR)) { // cout << "Diretorio ja existe\n"; ->log @@ -208,63 +236,67 @@ bool server::create_received_dir() { return true; } -string server::receive_file_name() { - frame *fReceive; - - // 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 - */ - // cout << "Recebendo nome do arquivo\n";->log - - do { - // cout << "Aguardando frame\n";->log - fReceive = receive_frame_socket(); - if (!fReceive) { return string{}; } - - // cout << "Frame recebido\n";->log - - if (fReceive->get_tipo() != MIDIA) { continue; } - if (fReceive->get_seq() != 1) { - // cout << "Sequencia errada\n";->log - fReceive->set_seq(0); - send_ack(fReceive); - continue; - } - - if (verify_crc8(fReceive)) { break; } - - // cout << "Crc invalido, aguardando retransmissao\n"; ->log - - } while (true); - - // cout << "Nome do arquivo recebido com sucesso\n"; ->log - // cout << "Nome do arquivo: " << fReceive->get_dado() << "\n"; ->log - - return string(fReceive->get_dado()); -} - -bool server::verify_seq(int seq, int lastSeq) { - // cout << "seq: " << seq << " lastSeq: " << dec << lastSeq << "\n"; ->log - if (seq == 0) { - if (lastSeq != 15) { return false; } - return true; - } - - if (seq != lastSeq + 1) { return false; } - return true; -} - -int server::receive_file_data(string fileName) { +//int server::receive_file_data(string fileName) { +// +// int lastSeq = 1; +// frame *f; +// +// cout << "\tRecebendo dados arquivo\n"; +// do { +// cout << "Aguardando frame\n"; +// +// // Fica tentando receber um frame +// f = receive_frame_socket(); +// if (f == NULL) { return 0; } +// +// cout << "Frame recebido\n"; +// f->imprime(HEX); +// +// if (f->get_tipo() == FIMT) { break; } +// +// if (f->get_tipo() != DADOS) { continue; } +// +// if (f->get_seq() == lastSeq) { continue; } +// +// // Recebeu um frame com uma sequencia errada +// if (!verify_seq(f->get_seq(), lastSeq)) { +// cout << "Frame com a sequencia errada; Pedindo a certa\n"; +// f->set_seq(lastSeq); +// send_ack(f); +// continue; +// } +// +// if (!verify_crc8(f)) { +// cout << "Crc invalido\n"; +// continue; +// } +// +// cout << "Seq " << int(f->get_seq()) << "recebida com sucesso\n"; +// lastSeq = f->get_seq(); +// file.write(f->get_dado(), f->get_tam()); +// +// } while (true); +// +// cout << "Dados do arquivo recebido com sucesso\n"; +// send_ack(f); +// +// file.close(); +// return 1; +//} +// + +string server::create_file_destination(string fileName) +{ string fileDestination; fileDestination.append(FILE_DESTINATION); fileDestination.push_back('/'); fileDestination.append(fileName); + return fileDestination; +} + +ofstream server::create_file(string fileName) { + string fileDestination = create_file_destination(fileName); cout << BOLDWHITE << "Criando arquivo " << BOLDYELLOW << fileDestination << BOLDWHITE << ". Digite novo nome ou enter para continuar: " << RESET; @@ -280,79 +312,46 @@ int server::receive_file_data(string fileName) { // Abre o arquivo para escrita ofstream file; file.open(fileDestination, ios::binary); - if (!file.is_open()) { - cout << RED << "\tFalha ao criar o arquivo. Abortado\n" << RESET; - return 0; - } - - int lastSeq = 1; - frame *f; - - cout << YELLOW << "\t--Recebendo dados arquivo--\n" << RESET; - do { - // Fica tentando receber um frame - f = receive_frame_socket(); - if (f == NULL) { - // cout << BOLDRED << "\tErro ao receber dados do arquivo\n" << RESET; - // ->log - file.close(); - remove(fileDestination.c_str()); - return 0; - } - - // f->imprime(HEX); ->log - - if (f->get_tipo() == FIMT) { break; } - - if (f->get_tipo() != DADOS) { continue; } - - if (f->get_seq() == lastSeq) { continue; } - - // Recebeu um frame com uma sequencia errada - if (!verify_seq(f->get_seq(), lastSeq)) { - // cout << "Frame com a sequencia errada; Pedindo a certa\n"; ->log - f->set_seq(lastSeq); - send_ack(f); - continue; - } + return file; +} - if (!verify_crc8(f)) { - // cout << "Crc invalido\n"; ->log - continue; - } +int server::receive_midia(frame *f) { + + ofstream file; - // cout << "Seq " << int(f->get_seq()) << "recebida com sucesso\n"; ->log - lastSeq = f->get_seq(); + // Escreve o dado no arquivo + if ( f->get_tipo() == DADOS ) + { file.write(f->get_dado(), f->get_tam()); + return 1; + } - } while (true); - - // cout << "\tDados do arquivo recebido com sucesso\n"; ->log - send_ack(f); - - file.close(); - return 1; -} - -void server::receive_midia(frame *f) { - cout << BOLDYELLOW << "\t--Recebendo arquivo--\n" << RESET; - // cout << "Recebendo frame midia\n"; ->log - if (!create_received_dir()) { return; } - if (!receive_file_size(f)) { return; } - - string fileName = receive_file_name(); + // Primeiro frame de midia + if ( f->get_seq() == 0 ) + { + cout << "Recebendo tamanho do arquivo\n"; + if (!create_received_dir()) { return 0; } + if (!receive_file_size(f)) { return 0; } + } - if (fileName.size() == 0) { return; } + // Segundo frame de midia + string fileName = string(f->get_dado()); + file = create_file(fileName); - if (!receive_file_data(fileName)) { - cout << BOLDRED << "\t--Falha ao receber o arquivo\n--" << RESET; - return; + if (!file.is_open()) + { + cout << RED << "\tFalha ao criar o arquivo. Abortado\n" << RESET; + file.close(); + remove(create_file_destination(fileName).c_str()); + return 0; } - cout << BOLDGREEN << "\t--Arquivo recebido com sucesso--\n" << RESET; + // cout << BOLDGREEN << "\t--Arquivo recebido com sucesso--\n" << RESET; + if ( !file.is_open() ) { return 0; } + return 1; } -// Recebe um frame do cliente +//// Recebe um frame do cliente frame *server::receive_frame_socket() { frame *fReceive; int retries = 0; @@ -369,54 +368,205 @@ 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) { +// +// do { +// // Se nao conseguir receber o frame, mata a comunicacao +// *f = receive_frame_socket(); +// if (*f == NULL) { return 0; } +// +// // Avisa o cliente se nao conseguiu receber o frame +// } while (!verify_crc8(*f)); +// return 1; +//} + +queue<frame *> server::receive_frames_window(int lastSeq) +{ + queue<frame *> frames_queue; + frame *f; + int retries = 0; -bool server::verify_crc8(frame *f) { - int crc8 = f->chk_crc8(); - if (!crc8) { - send_nack(f); - } else - send_ack(f); - return crc8; -} + do { + if ( ! (f = receive_frame_socket()) ) { continue; } + + retries++; -int server::receive_valid_frame(frame **f) { + int tipo = f->get_tipo(); - do { - // Se nao conseguir receber o frame, mata a comunicacao - *f = receive_frame_socket(); - if (*f == NULL) { return 0; } + // Adiciona o frame de fim de transmissao + if ( tipo == FIMT ) + { + frames_queue.push(f); + return frames_queue; + } - // Avisa o cliente se nao conseguiu receber o frame - } while (!verify_crc8(*f)); - return 1; + // Primeiro frame a ser recebido, seta o tipo + if ( lastSeq == -1 ) + { + // Ignora os frames perdidos na linha + if ( (tipo != MIDIA && tipo != TEXTO) || f->get_seq() != 0 ) {continue;} + tipoReceivingFrames = f->get_tipo(); + frames_queue.push(f); + lastSeq = 0; + retries = 0; + continue; + } + + + // Ignora se o frame nao for do tipo midia e esteja recebendo midia + if ( tipo == MIDIA && tipoReceivingFrames == MIDIA ) + { + // Ignora se for um frame do tipo midia que nao e o segundo da sequencia + if ( lastSeq != 0 || (TAM_JANELA > 1 && f->get_seq() != 1)) { continue; } + + // Se for o segundo frame do tipo midia, muda o tipo esperado + tipoReceivingFrames = DADOS; + frames_queue.push(f); + lastSeq = 1; + retries = 0; + continue; + } + + // Recebe os frames de dados de um arquivo + if ( tipoReceivingFrames == DADOS && tipo == DADOS ) + { + if ( !verify_seq(f->get_seq(), lastSeq) ) { continue; } + frames_queue.push(f); + retries = 0; + lastSeq = f->get_seq(); + continue; + } + + // Recebe os frames de uma mensagem + if ( tipoReceivingFrames == TEXTO && tipo == TEXTO ) + { + if ( !verify_seq(f->get_seq(), lastSeq) ) { continue; } + frames_queue.push(f); + retries = 0; + lastSeq = f->get_seq(); + continue; + } + + } while ( (f == NULL && retries < NUM_RETRIES) || frames_queue.size() < TAM_JANELA ); + + if ( f == NULL && retries == NUM_RETRIES ) { return queue<frame *>(); } + + return frames_queue; } void server::start_receveing_message() { int continueTransmission = 1; + int lastSeq = -1; + int tipo_data = -1; + vector<char> data; + queue<frame *> client_answer; - // cout << "Recebendo frames\n"; ->log - frame *f; + cout << "Recebendo frames\n"; + // Fic aouvindo o cliente ate receber um FIMT do { - if (!receive_valid_frame(&f)) { return; } - if (!f) { return; } - int frameType = f->get_tipo(); - - switch (frameType) { - case TEXTO: - receive_text(f); - continueTransmission = 0; - break; - - case MIDIA: - receive_midia(f); - continueTransmission = 0; - break; - - default: - break; + queue<frame *> frames = receive_frames_window(lastSeq); + if ( frames.empty() ) { return; } + + cout << "Quantidade de frames na janela: " << frames.size() << "\n"; + + // Ve o que faz com cada frame de acordo com o tipo + while ( !frames.empty() ) + { + frame *f = frames.front(); + frames.pop(); + + // Recebeu um frame com erro, retorna um nack e sai da funcao + if ( !f->chk_crc8() ) { + client_answer.push(create_ack_nack(NACK, f->get_seq())); + continue; + } + + else { + client_answer.push(create_ack_nack(ACK, f->get_seq())); + } + + cout << "Frame recebido: \n"; + f->imprime(HEX); + cout << "\n"; + + int tipo = f->get_tipo(); + int tam = f->get_tam(); + char *data_f = f->get_dado(); + + switch (tipo) + { + case FIMT: + cout << "Encerrou a transmissao\n"; + continueTransmission = 0; + break; + + case TEXTO: + data.insert(data.end(), data_f, data_f + tam); + lastSeq = f->get_seq(); + tipo_data = TEXTO; + break; + + case MIDIA: + if ( !receive_midia(f) ) { return; } + lastSeq = f->get_seq(); + tipo_data = next_tipo_midia(f); + break; + + case DADOS: + if ( !receive_midia(f)) { return; } + lastSeq = f->get_seq(); + tipo_data = DADOS; + break; + + default: + break; + } } + cout << "Recebeu todos os frames de uma janela\n"; + + // Envia a reposta ao cliente + cout << "Enviando acks e nacks para o cliente\n"; + while ( !client_answer.empty() ) + { + frame *f_answer = client_answer.front(); + client_answer.pop(); + + if (socket->send_frame(f_answer) == -1 ) + { + cout << "Falha ao enviar a resposta\n"; + return; + } + + if (f_answer->get_tipo() == NACK) + cout << "NACK " << (int)f_answer->get_dado()[0] << " enviado\n"; + + else + cout << "ACK " << (int)f_answer->get_dado()[0] << " enviado\n"; + } + + cout << "Todos os ACKs e NACKs foram enviados\n"; + } while (continueTransmission); + + if ( tipo_data == TEXTO ) + cout << BOLDYELLOW << "\t--Mensagem recebida--\n " << BOLDWHITE + << string(data.begin(), data.end()) << "\n" + << RESET; + + if ( tipo_data == DADOS ) + cout << BOLDGREEN << "\t--Arquivo recebido com sucesso--\n" << RESET; } // ------------------------------- PUBLIC --------------------------------- // @@ -445,7 +595,7 @@ void server::run() { continue; } - send_ack(fReceive); + if ( send_ack(fReceive) == -1 ) { continue; } start_receveing_message(); } } diff --git a/received/135828 b/received/135828 new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/received/foto.jpg b/received/foto.jpg index 42cedf4a23e28ccea764d16047faa18f7149ddb8..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 Binary files a/received/foto.jpg and b/received/foto.jpg differ diff --git a/received/texto.txt b/received/texto.txt index 16914e72e0641b9e2ae68d9c8aef608f1fed464f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/received/texto.txt +++ b/received/texto.txt @@ -1,35 +0,0 @@ - //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; - //} - diff --git a/received/todo.txt b/received/todo.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/text.txt b/text.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/todo.txt b/todo.txt index 108fd2179e3697be302e7ce014a92334f71f5b9d..72ff90813754027306bdbe261c52b201bbe528ef 100644 --- a/todo.txt +++ b/todo.txt @@ -1,15 +1,15 @@ -> Ver se os frames que estao vindo sao arquivos e juntar eles no arquivo +<<<<<<< HEAD -> Fazer send_error -> Arrumar o receive text +======= +>>>>>>> db29f5efa0a686ffe08f19d3553a889be3c6e4d5 -> Arrumar a interface --> Merge correcao de erro - -> Enviar arquivo correcao de erros - -> Readme - -> Demonstracao +-> Demonstracao correcao de erros -> Janela deslizante -> Demonstracao