diff --git a/include/messages.h b/include/messages.h index b31d5554d939d05c3cd375930f3f1d743152804c..a8fcd742cbe15693e026a693c2622497c3c76690 100644 --- a/include/messages.h +++ b/include/messages.h @@ -13,10 +13,17 @@ class Message{ SubMessage messages[3]; // Janela deslizante permite 3 mensagens de uma vez public: - int sendCD(unsigned char*); + // Métodos que fazem as requisições dos comandos + int sendCD(unsigned char*); int sendLS(unsigned char*); int sendPUT(unsigned char*); int sendGET(unsigned char*); int sendData(unsigned char*); // Método que divide e envia uma mensagem. - // int receiveMessage(); // Método que recebe as mensagens e as agrupa + + // Métodos que faz o recebimento e resposta aos comandos + int receiveCD(unsigned char*); // Lida com mensagens tipo CD + int receiveLS(unsigned char*); // Lida com mensagens tipo LS + int receivePUT(unsigned char*); // Lida com... ok você entendeu + int receiveGET(unsigned char*); + int receiveData(unsigned char*, int); // Método que recebe as mensagens e as agrupa }; diff --git a/src/messages.cpp b/src/messages.cpp index 974a71631a29f26ba440bc7fcdd3491e2f119b83..90baff5ad815e2f799fff274d627ca22b4547331 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -307,8 +307,13 @@ int Message::sendGET(unsigned char* fileName){ } else { ok.setData((unsigned char*)answer.getSeq(),8,0); // Manda um ok send(soquete,ok.objToString(),ok.getSize()+4, 0); - funcaoRecebeDados(); - return 0; + if(receiveData(fileName,atoi(answer.getData())) == -1){ + cout << "Erro no recebimento de dados (messages.cpp::sendGET)" << endl; + return -1; + } else{ + cout << "Arquivo transferido com sucesso" << endl; + return 0; + } } } } @@ -414,19 +419,19 @@ int Message::sendData(unsigned char* stringMessage){ // Lê começo da mensagem e vê se tem o delimitador de início if(answer.getStartMessage() == 0x7E){ // 0x7E = 01111110 if(numberOfMessages == 1){ - if(answer.getData()[0] == '1'){ + if(answer.getType() == 1){ //ACK success = 1; // YAY } else { cout << "Mensagem entregue com erro (messages.cpp::sendData)" << endl; } } else if (numberOfMessages == 2){ // numero de mensagens = 2 - if(answer.getData() == (unsigned char*)"1 1"){ // aceitou ambas as msgs + if((answer.getType() == 1) && (answer.getData() == (unsigned char*)'1') ){ // aceitou ambas as msgs success = 1; // YAY } else { cout << "Mensagem entregue com erro (messages.cpp::sendData)" << endl; } } else { // numbero de mensagens = 3 - if(answer.getData() == (unsigned char*)"1 2"){ // aceitou ambas as msgs + if((answer.getType() == 1) && (answer.getData() == (unsigned char*)'2') ){ // aceitou ambas as msgs success = 1; // YAY } else { cout << "Mensagem entregue com erro (messages.cpp::sendData)" << endl; @@ -444,8 +449,10 @@ int Message::sendData(unsigned char* stringMessage){ i = 0; while (i < numberOfMessages - 2){ error = send(soquete, subMensagem[i].objToString() , subMensagem[i].getSize()+4, 0); - error = send(soquete, subMensagem[i+1].objToString() , subMensagem[i].getSize()+4, 0); - error = send(soquete, subMensagem[i+2].objToString() , subMensagem[i].getSize()+4, 0); + if(i < numberOfMessages - 1) + error = send(soquete, subMensagem[i+1].objToString() , subMensagem[i].getSize()+4, 0); + if(i < numberOfMessages) + error = send(soquete, subMensagem[i+2].objToString() , subMensagem[i].getSize()+4, 0); success = 0; garbage = 0; @@ -475,6 +482,8 @@ int Message::sendData(unsigned char* stringMessage){ } else { success = 0; } + } else if (answer.getType() == 0){ + success = 0; // NACK } } } @@ -488,3 +497,91 @@ int Message::sendData(unsigned char* stringMessage){ } return 0; } + +//################# MÉTODOS DA CLASSE Message --> Recebimento ################# + +int receiveData(unsigned char* fileName, int size){ + int numberOfMessages, messagesCounter = 0, seqCounter; + int i, garbage, error, rv, success = 0, greaterSeq = 0; + unsigned char *subData; + char *receiptMessage = (char*)malloc(sizeof(char*)*64); + struct pollfd ufds[1]; + SubMessage nack, ack, answer; + ofstream fileOut; + map<int,string> subMensagem; + string finalMessage; + + ufds[0].fd = soquete; + ufds[0].events = POLLIN; + + // Verifica quantas mensagens serao necessarias + if (size%64){ + numberOfMessages = (size/64) + 1; + }else{ + numberOfMessages = (size/64); + } + numberOfMessages++; // +1 = Mensagem de FIM + +while(!success){ + rv = poll(ufds, 1, 500); + if(rv){ + if(rv == -1){ + cout << "Erro no recebimento dos dados (messages.cpp::receiveData)" << endl; + return -1; + }else{ + recv(soquete, receiptMessage, 68*sizeof(char), 0); + answer.stringToObj((unsigned char*)receiptMessage); + // Lê começo da mensagem e vê se tem o delimitador de início + if(answer.getStartMessage() == 0x7E){ // 0x7E = 01111110 + if(answer.checkParity()){ + if(messagesCounter == 0){ // Se a primeira mensagem tiver erro + nack.setData((unsigned char*)answer.getSeq(),0,0); // Manda um nack + send(soquete,nack.objToString(),nack.getSize()+4, 0); + }else{ + ack.setData((unsigned char*)((answer.getSeq()-1)%64),1,0); + send(soquete, ack.objToString(), ack.getSize()+4, 0); // Manda um ACK + messagesCounter = 0; + } + }else{ + if(answer.getType() == 13){ + if(subMensagem[answer.getSeq()+(seqCounter*64)] == ""){ + if(answer.getSeq() == 63){ + seqCounter++; + } + subMensagem[answer.getSeq()+(seqCounter*64)] = (char*)answer.getData(); + messagesCounter++; + if(answer.getSeq()+(seqCounter*64) > greaterSeq){ + greaterSeq = answer.getSeq()+(seqCounter*64); + } + if(messagesCounter > 2){ + ack.setData((unsigned char*)(greaterSeq%64),1,0); + send(soquete, ack.objToString(), ack.getSize()+4, 0); // Manda um ACK + messagesCounter = 0; + } + }else{ + ack.setData((unsigned char*)answer.getSeq(),1,0); + send(soquete, ack.objToString(), ack.getSize()+4, 0); // Manda um ACK + messagesCounter = 0; + } + }else if(answer.getType() == 15){ + success = 1; + ack.setData((unsigned char*)((greaterSeq%64)+1),1,0); + send(soquete, ack.objToString(), ack.getSize()+4, 0); // Manda um ACK + } + } + } + } + }else{ + cout << "Tempo limite de resposta excedido :c\n" << endl; + cout << "TIMEOUT ATINGIDO (messages.cpp::receiveData)" << endl; + } + } + + for(i = 0; i < greaterSeq; ++i){ + finalMessage += subMensagem[i]; + } + // Escrita no arquivo de saída. + fileOut.open(fileName, ios::out); + fileOut << finalMessage; + return 0; +}