diff --git a/Message.cpp b/Message.cpp
index 42422257d164565b3156c046e812779fea7e1f67..8e99a3dc1a9ab95ad898fbe9a2f9a5b73924304c 100644
--- a/Message.cpp
+++ b/Message.cpp
@@ -67,27 +67,10 @@ int Message::getMessageSize(){
     return size.to_ulong()+4;
 }
 
-// string Message::getSendData() {
-//     calcParity();
-//     string s(data.begin(), data.end());
-//     int size = data.size();
-//     //TODO: quebrar em partes aqui? ou tem que quebrar no protocolo?
-//     header.i_ctrl.size = size;
-//     header.i_ctrl.sequence = 1;
-//     char *fill;
-//     if(size < 63) {
-//         fill = (char*) malloc((63-size)*sizeof(char));
-//         memset(fill, 0, (63-size)*sizeof(char));
-//     }
-//     string d;
-//     d += header.c_ctrl.begin;
-//     d += header.c_ctrl.sizeSeq;
-//     d += header.c_ctrl.seqType;
-//     d += s.c_str();
-//     d += fill;
-//     d += header.c_ctrl.parity;
-//     return d;
-// }
+int Message::dataToInt() {
+    string str(data.begin(), data.end());
+    return stoi(str);
+}
 
 ostream& operator<<(ostream& os, const Message& msg){
     os << '|' << msg.begin << '|' << msg.size << '|' << msg.sequence << '|' << msg.type << '|';
diff --git a/Message.h b/Message.h
index 24f3bbe6d9b344cd5926a26584e3268868de2f8b..71fa12128e4468547b9c5a6e82f257aa7d9e07b0 100644
--- a/Message.h
+++ b/Message.h
@@ -14,12 +14,12 @@ public:
 
     BYTE calcParity();
     bool checkParity();
-    // string getSendData();
     void setBitFields(BYTE begin, BYTE sizeSeq, BYTE seqType, BYTE parity);
     vector<BYTE> getBitFieldsAsBytes();
     vector<BYTE> getMessage();
     char* getMessageAsCharPointer();
     int getMessageSize();
+    int dataToInt();
 
     Message();
 };
diff --git a/Protocol.cpp b/Protocol.cpp
index 4cf051250a0ed046efab6149f3e8a414990b4b61..02f2ef78de83e39f9a8ea586d30c748e08893a16 100644
--- a/Protocol.cpp
+++ b/Protocol.cpp
@@ -10,19 +10,29 @@ void Protocol::setMessages(vector<Message> messages){
     this->messages = messages;
 }
 
-bool Protocol::sendMessages(int socket, int window) {
+bool Protocol::sendMessages(int socket) {
+    bool success = true;
     for(int i=0; i < messages.size(); ++i) {
-        // cout << "message: " << messages[i] << endl;
-        vector<BYTE> message = messages[i].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;
-        send(socket, msg, messages[i].getMessageSize(), 0);
+        int status = sendMessage(socket, i);
+        if(status < 0) {
+            success = false;
+            cout << "fail" << endl;
+        }
     }
-    return true;
+    return success;
+}
+
+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);
 }
 
 vector<BYTE> Protocol::getData(){
@@ -78,17 +88,17 @@ int Protocol::recvMessage(int sockt){
     BYTE dataRec[MAXSIZE+4];
     int r = recv(sockt, dataRec, MAXSIZE+4, 0);
     cout << bitset<8>(dataRec[0]) << "|" << bitset<8>(dataRec[1]) << "|" << bitset<8>(dataRec[2]) << "|" << bitset<8>(dataRec[3]) << "|\t";
-    cout << "recv response: " << r << endl;
+    // cout << "recv response: " << r << endl;
     if(dataRec[0] != BEGIN){
         return NOISE;
     }
     Message msg = Message();
     int size = (int)(dataRec[1]>>2);
-    cout << "Tamanho:" << size << "\t";
+    // 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)))){
+    // cout << "Sequence:" << msg.sequence.to_ulong() << "\t";
+    if(!receivedMessages.empty() &&
+        (msg.sequence.to_ulong() != ((receivedMessages.back().sequence.to_ulong()+1)%(MAXSIZE+1))) && (msg.sequence.to_ulong() != receivedMessages.back().sequence.to_ulong()) ){
         return SEQ_MISS;
     }
     if(!msg.checkParity()){
@@ -101,22 +111,52 @@ int Protocol::recvMessage(int sockt){
     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;
+    receivedMessages.push_back(msg);
+    // cout << "Tipo:" << (int)msg.type.to_ulong() << endl;
     return (int)msg.type.to_ulong();
 }
 
-void Protocol::transmit(int sockt, int type, int window){
+void Protocol::transmit(int sockt, int window){
     int status;
-    for(int i=0; i < messages.size(); ++i){
-        //TODO: send part of output back
+    vector<int> frame;
+    int lastFramed = 0;
+    int messagesLeft = messages.size();
+    bool shouldSend = true;
+    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);
-        if(!status){
-            //TODO: send part of output back again
+        cout << "transmit status:" << status << endl;
+        shouldSend = true;
+        if(status == 0){
+            int nackIndex = stoi(getDataAsString());
+            for(int j=0; j < window; ++j) {
+                if(frame[j] < nackIndex) {
+                    frame.erase(frame.begin() + j);
+                    --messagesLeft;
+                }
+            }
         }else if(status == 1){
-            //TODO: send another part of output back
-        }else{
-            //TODO: send NACK back
+            int ackIndex = stoi(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;
+        } else {
+            //TODO: treat error
+            shouldSend = false;
         }
     }
 }
diff --git a/Protocol.h b/Protocol.h
index 8475424efe026b74983904a8f423a32d5d49fbd8..460d2dbb8e8e6de143db783306932fcce9cef451 100644
--- a/Protocol.h
+++ b/Protocol.h
@@ -7,9 +7,11 @@ class Protocol{
 
 private:
     vector<Message> messages;
+    vector<Message> receivedMessages;
     int timeout;
 public:
-    bool sendMessages(int socket, int window);
+    bool sendMessages(int socket);
+    bool sendMessage(int socket, int index);
     vector<Message> getMessages();
     void setMessages(vector<Message> messages);
     vector<BYTE> getData();
@@ -17,7 +19,7 @@ public:
     string getDataAsString();
     int recvMessage(int sockt);
     void addMessage(Message msg);
-    void transmit(int sockt, int type, int window);
+    void transmit(int sockt, int window);
     void receive(int sockt, int type, int window);
 
     Protocol();
diff --git a/client.cpp b/client.cpp
index e8eeb56b971c0d9bf12773dda3fbba5c772ec52c..06717ec0c7cf55dbb84b35ca34a4c31b1840dafe 100644
--- a/client.cpp
+++ b/client.cpp
@@ -31,17 +31,17 @@ int main(){
             }else if(command == "cdr"){
                 args = line.substr(pos+1, line.size());
                 protocol.setData(vector<BYTE>(args.begin(), args.end()), CD);
-                protocol.sendMessages(sockt, WAIT_STOP);
+                protocol.transmit(sockt, WAIT_STOP);
             }else if(command == "lsr"){
-                Message msg = Message();
                 line.replace(line.find("lsr"), string("lsr").length(), "ls");
                 protocol.setData(vector<BYTE>(line.begin(), line.end()), LS);
-                protocol.sendMessages(sockt, WAIT_STOP);
-                // TODO: imprimir resposta
+                protocol.transmit(sockt, WAIT_STOP);
             }else if(command == "put"){
-                //TODO
+                protocol.setData(vector<BYTE>(line.begin(), line.end()), PUT);
+                protocol.transmit(sockt, WAIT_STOP);
             }else if(command == "get"){
-
+                protocol.setData(vector<BYTE>(line.begin(), line.end()), GET);
+                protocol.transmit(sockt, WAIT_STOP);
             }else if(command == "help"){
                 printCommandsList();
             }else{
@@ -53,24 +53,6 @@ int main(){
         }catch(out_of_range e){
             cerr<<"Error: Esse comando requer argumentos."<<endl;
         }
-
-        // int status = protocol.recvMessage(sockt);
-        // cout << "Status: " << status << endl;
-        // if(status > 0){
-        //     if(status == ENDTX){
-        //         protocol = Protocol();
-        //         //TODO: send ACK
-        //     }else if(status == CD){
-        //         cd(protocol.getDataAsString());
-        //     }else if(status == LS){
-        //         string output = ls(protocol.getDataAsString());
-        //         //TODO: send output back
-        //     }else if(status == PUT){
-        //         //TODO
-        //     }else if(status == GET){
-        //         //TODO
-        //     }
-        // }
     }
     return 0;
 }
diff --git a/server.cpp b/server.cpp
index 264c5085aefeeb2437960750b321b3dfae2b0b4f..16db764a2c5aee8ac6fb359297eb625adbb99bf0 100644
--- a/server.cpp
+++ b/server.cpp
@@ -19,9 +19,11 @@ int main(){
                 cout << "Recebeu CD\n";
                 cd(protocol.getDataAsString());
             }else if(status == LS){
-                cout << "Recebeu LS\n";
+                cout << protocol.getDataAsString() << endl;
                 string output = ls(protocol.getDataAsString());
-                //TODO: send output back
+                cout << "LS:" << output << endl;
+                protocol.setData(vector<BYTE>(output.begin(), output.end()), OUTPUT);
+                protocol.sendMessages(sockt);
             }else if(status == PUT){
                 //TODO
             }else if(status == GET){