diff --git a/Message.cpp b/Message.cpp
index 8e99a3dc1a9ab95ad898fbe9a2f9a5b73924304c..4461bcc52ff491dea224c3bc4bdf4e4e775e95d0 100644
--- a/Message.cpp
+++ b/Message.cpp
@@ -72,6 +72,11 @@ int Message::dataToInt() {
     return stoi(str);
 }
 
+string Message::getDataAsString() {
+    string str(data.begin(), data.end());
+    return str;
+}
+
 ostream& operator<<(ostream& os, const Message& msg){
     os << '|' << msg.begin << '|' << msg.size << '|' << msg.sequence << '|' << msg.type << '|';
     // os << msg.begin << msg.size << msg.sequence << msg.type;
diff --git a/Message.h b/Message.h
index 71fa12128e4468547b9c5a6e82f257aa7d9e07b0..6056953d4633ff2bbac5bbf5170d04767767a87e 100644
--- a/Message.h
+++ b/Message.h
@@ -20,6 +20,7 @@ public:
     char* getMessageAsCharPointer();
     int getMessageSize();
     int dataToInt();
+    string getDataAsString();
 
     Message();
 };
diff --git a/Protocol.cpp b/Protocol.cpp
index a3142c27604c69424f6ca4c0b212146403b5b1e1..efb88761e617dc787390927c0ab20aafb98d0920 100644
--- a/Protocol.cpp
+++ b/Protocol.cpp
@@ -25,11 +25,6 @@ bool Protocol::sendMessage(int socket, int index) {
     cout << "message: " << messages[index] << endl;
     vector<BYTE> message = messages[index].getMessage();
     unsigned char* msg = reinterpret_cast<unsigned char*> (message.data());
-    // cout << "char* msg: ";
-    // for(int j=0;j<message.size();++j){
-    //     cout << bitset<8>(msg[j]);
-    // }
-    // cout <<endl;
     int status = send(socket, msg, messages[index].getMessageSize(), 0);
     return (status >= 0);
 }
@@ -69,7 +64,7 @@ int Protocol::setData(vector<BYTE> data, int type){
         msg.type = bitset<TYPE_S>(type);
         int size = ((int)data.size())-i;
         first = data.begin()+i;
-        last = data.begin()+size+1;
+        last = data.begin()+i+size+1;
         vector<BYTE> subvector(first, last);
         msg.data = subvector;
         if(size < MINSIZE){
@@ -97,22 +92,17 @@ int Protocol::recvMessage(int sockt){
     cout << "Tamanho:" << size << "\t";
     msg.setBitFields(dataRec[0], dataRec[1], dataRec[2], dataRec[size+3]);
     cout << "Sequence:" << msg.sequence.to_ulong() << "\t";
-    if(!messages.empty() &&
-        (msg.sequence.to_ulong() != ((messages.back().sequence.to_ulong()+1)%(MAXSIZE+1)))){
-        return SEQ_MISS;
-    }
-    if(!msg.checkParity()){
-        return INCONSISTENT;
-    }
-    if(msg.type.to_ulong() == ENDTX){
-        return ENDTX;
-    }
 
     BYTE msgData[size];
     memcpy(msgData,dataRec+3,size);
     msg.data.insert(msg.data.end(), msgData, msgData+size);
+
     messages.push_back(msg);
     cout << "Tipo:" << (int)msg.type.to_ulong() << endl;
+
+    if(!msg.checkParity()){
+        return INCONSISTENT;
+    }
     return (int)msg.type.to_ulong();
 }
 
@@ -122,54 +112,94 @@ void Protocol::transmit(int sockt, int window){
     int lastFramed = 0;
     int messagesLeft = messages.size();
     bool shouldSend = true;
+    Protocol response;
     while(messagesLeft > 0){
         for(int j=0; j < window; ++j) {
             frame.push_back(lastFramed++);
             if(shouldSend) sendMessage(sockt, frame[j]);
         }
         // TODO: timeout
-        status = recvMessage(sockt);
+        status = response.recvMessage(sockt);
         cout << "transmit status:" << status << endl;
         shouldSend = true;
-        if(status == 0){
-            int nackIndex = stoi(getDataAsString());
+        if(status == NACK){
+            int nackIndex = stoi(response.getMessages().back().getDataAsString());
             for(int j=0; j < window; ++j) {
                 if(frame[j] < nackIndex) {
                     frame.erase(frame.begin() + j);
                     --messagesLeft;
                 }
             }
-        }else if(status == 1){
-            int ackIndex = stoi(getDataAsString());
+            response.reset();
+
+        }else if(status == ACK){
+            int ackIndex = stoi(response.getMessages().back().getDataAsString());
             for(int j=0; j < window; ++j) {
                 if(frame[j] <= ackIndex) {
                     frame.erase(frame.begin() + j);
                     --messagesLeft;
                 }
             }
-        }else if(status == OK) {
-            frame.erase(frame.begin());
-            --messagesLeft;
-        } else if(status == OUTPUT || status == ERROR) {
-            frame.erase(frame.begin());
-            --messagesLeft;
-            cout << "Remoto:\n" << ((status == ERROR)?"ERROR: ":"") << getDataAsString() << endl;
+            response.reset();
+        // }else if(status == OK) {
+        //     frame.erase(frame.begin());
+        //     --messagesLeft;
+        // } else if(status == OUTPUT || status == ERROR) {
+        //     frame.erase(frame.begin());
+        //     --messagesLeft;
+        //     cout << "Remoto:\n" << ((status == ERROR)?"ERROR: ":"") << getDataAsString() << endl;
         } else {
             //TODO: treat error
             shouldSend = false;
         }
     }
+    reset();
+    vector<BYTE> val(1,(BYTE)0);
+    setData(val, ENDTX);
+    sendMessage(sockt,0);
 }
 
-void Protocol::receive(int sockt, int type, int window){
-    int status;
+void Protocol::receive(int sockt, int window){
+    int status, nextSequence;
+    vector<int> frame;
+    Protocol response;
+    bool shouldSend = false;
     do{
+        if(shouldSend){
+            response.sendMessages(sockt);
+        }
         status = recvMessage(sockt);
-        if(status == type){
-            //TODO: send ACK back
+        if(status == NOISE){
+            continue;
+        }else if(response.getMessages().back().sequence.to_ulong() != nextSequence){
+            response.reset();
+            vector<BYTE> val(1,(BYTE)nextSequence);
+            response.setData(val, NACK);
+            shouldSend = true;
+        }
+        else if(status == OUTPUT) {
+            cout << messages.back().getDataAsString();
+
+            frame.push_back(messages.size());
+
+            response.reset();
+            vector<BYTE> val(1,(BYTE)messages.back().sequence.to_ulong());
+            response.setData(val, ACK);
+            nextSequence = (messages.back().sequence.to_ulong()+1)%(MAXSIZE+1);
+        }else if(status == ERROR){
+            string str(messages.back().data.begin(), messages.back().data.end());
+            cout << "ERROR: " << getDataAsString() << endl;
+            break;
+        }else if(status == INCONSISTENT){
+            response.reset();
+            vector<BYTE> val(1,(BYTE)nextSequence);
+            response.setData(val, NACK);
+            shouldSend = true;
         }else{
-            //TODO: send NACK back
+            //TODO: treat error
+            break;
         }
+        shouldSend = shouldSend || (frame.size()%window == 0);
     }while(status != ENDTX);
 }
 
@@ -177,5 +207,9 @@ void Protocol::addMessage(Message msg) {
     messages.push_back(msg);
 }
 
+void Protocol::reset(){
+    messages.clear();
+}
+
 Protocol::Protocol(){
 }
diff --git a/Protocol.h b/Protocol.h
index 7642201db47b2ad215b228e42f94868ad37197b0..6577966eaf665acc47778b9ff3497f1a4b3e0d2a 100644
--- a/Protocol.h
+++ b/Protocol.h
@@ -19,7 +19,8 @@ public:
     int recvMessage(int sockt);
     void addMessage(Message msg);
     void transmit(int sockt, int window);
-    void receive(int sockt, int type, int window);
+    void receive(int sockt, int window);
+    void reset();
 
     Protocol();
 };
diff --git a/client.cpp b/client.cpp
index 06717ec0c7cf55dbb84b35ca34a4c31b1840dafe..4d261135fa919679c10ae70addce636bfc99cfaa 100644
--- a/client.cpp
+++ b/client.cpp
@@ -9,7 +9,7 @@ void printCommandsList();
 int main(){
     int pos, sockt = ConexaoRawSocket(DEVICE);
     string line, command, args;
-    Protocol protocol = Protocol();
+    Protocol receiveProtocol, sendProtocol;
     printCommandsList();
     while(true){
         cout << endl << "Entre com o comando:" << endl;
@@ -30,18 +30,21 @@ int main(){
                 cout << ls(line);
             }else if(command == "cdr"){
                 args = line.substr(pos+1, line.size());
-                protocol.setData(vector<BYTE>(args.begin(), args.end()), CD);
-                protocol.transmit(sockt, WAIT_STOP);
+                sendProtocol.setData(vector<BYTE>(args.begin(), args.end()), CD);
+                sendProtocol.transmit(sockt, WAIT_STOP);
             }else if(command == "lsr"){
                 line.replace(line.find("lsr"), string("lsr").length(), "ls");
-                protocol.setData(vector<BYTE>(line.begin(), line.end()), LS);
-                protocol.transmit(sockt, WAIT_STOP);
+                sendProtocol.setData(vector<BYTE>(line.begin(), line.end()), LS);
+                sendProtocol.sendMessage(sockt,0);
+                cout << "Remoto:" << endl;
+                receiveProtocol.receive(sockt, WAIT_STOP);
+                cout << endl;
             }else if(command == "put"){
-                protocol.setData(vector<BYTE>(line.begin(), line.end()), PUT);
-                protocol.transmit(sockt, WAIT_STOP);
+                sendProtocol.setData(vector<BYTE>(line.begin(), line.end()), PUT);
+                sendProtocol.transmit(sockt, WAIT_STOP);
             }else if(command == "get"){
-                protocol.setData(vector<BYTE>(line.begin(), line.end()), GET);
-                protocol.transmit(sockt, WAIT_STOP);
+                sendProtocol.setData(vector<BYTE>(line.begin(), line.end()), GET);
+                sendProtocol.transmit(sockt, WAIT_STOP);
             }else if(command == "help"){
                 printCommandsList();
             }else{
diff --git a/dirFunctions.cpp b/dirFunctions.cpp
index 0a8e9f07ac700728f65905f1619a8b7d5d3c0a9b..d0e7aa4509560a894ee75b0e4ce921724bd2bce2 100644
--- a/dirFunctions.cpp
+++ b/dirFunctions.cpp
@@ -27,4 +27,4 @@ string ls(string args){
     }
     pclose(lsOut);
     return output;
-}
\ No newline at end of file
+}
diff --git a/server.cpp b/server.cpp
index a6eb670226732d10f08e3015aa27fa48dbbe59dd..40b87c6c17ff25799ea748f11c6c2450b55ac60c 100644
--- a/server.cpp
+++ b/server.cpp
@@ -11,26 +11,30 @@ int main(){
         int status = receiveProtocol.recvMessage(sockt);
         cout << "status: " << status << endl;
         // cout << protocol.getDataAsString() << endl;
-        if(status > 0){
-            if(status == ENDTX){
-                // protocol = Protocol();
-                //TODO: send ACK
-            }else if(status == CD){
+        try{
+            if(status == NOISE){
+                continue;
+            }
+            if(status == CD){
                 cout << "Recebeu CD\n";
                 cd(receiveProtocol.getDataAsString());
             }else if(status == LS){
-                string output = ls(receiveProtocol.getDataAsString());
+                cout << "protocol data: " << receiveProtocol.getDataAsString() << endl;
+                cout << "message data: " << receiveProtocol.getMessages().back().getDataAsString() << endl;
+                string output = ls(receiveProtocol.getMessages().back().getDataAsString());
                 cout << "LS: " << output << endl;
-                // receiveProtocol = Protocol();
-                receiveProtocol.setData(vector<BYTE>(output.begin(), output.end()), OUTPUT);
-                receiveProtocol.sendMessages(sockt);
-                // sendProtocol = Protocol();
+                sendProtocol.setData(vector<BYTE>(output.begin(), output.end()), OUTPUT);
+                sendProtocol.transmit(sockt, WAIT_STOP);
             }else if(status == PUT){
                 //TODO
             }else if(status == GET){
                 //TODO
             }
+        }catch(char const* strException){
+            cout << "Erro:" <<strException <<endl;
         }
+        sendProtocol.reset();
+        receiveProtocol.reset();
     }
     return 0;
 }