diff --git a/Protocol.cpp b/Protocol.cpp
index 6a2613b5faedfb9b5c2a13f32f82070e8ba06516..cf0028cd3dc64ba6befb532f58dc5ffb4e510e39 100644
--- a/Protocol.cpp
+++ b/Protocol.cpp
@@ -27,7 +27,7 @@ bool Protocol::sendMessages(int socket) {
 }
 
 bool Protocol::sendMessage(int socket, int index) {
-    cout << "message: " << messages[index] << endl;
+    cout << "message sent: " << messages[index] << endl;
     vector<BYTE> message = messages[index].getMessage();
     unsigned char* msg = reinterpret_cast<unsigned char*> (message.data());
     int status = send(socket, msg, messages[index].getMessageSize(), 0);
@@ -88,7 +88,7 @@ int Protocol::setData(vector<BYTE> data, int type){
 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 << "begin: "<< bitset<8>(dataRec[0]) <<endl;
     cout << "recv response: " << r << endl;
     if(dataRec[0] != BEGIN){
         return NOISE;
@@ -99,7 +99,6 @@ int Protocol::recvMessage(int sockt){
     int dataSize = size < MINSIZE ? MINSIZE : size;
     msg.setBitFields(dataRec[0], dataRec[1], dataRec[2], dataRec[dataSize+3]);
     cout << "Sequence:" << msg.sequence.to_ulong() << "\t";
-
     BYTE msgData[size];
     memcpy(msgData,dataRec+3,size);
     msg.data.insert(msg.data.end(), msgData, msgData+size);
@@ -107,6 +106,7 @@ int Protocol::recvMessage(int sockt){
     messages.push_back(msg);
     cout << "Tipo:" << (int)msg.type.to_ulong() << endl;
 
+    cout <<"message received: "<< msg<<endl;
     if(!msg.checkParity()){
         return INCONSISTENT;
     }
@@ -155,13 +155,6 @@ void Protocol::transmit(int sockt, int window){
                 }
             }
             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
         }
@@ -186,58 +179,36 @@ int Protocol::receive(int sockt, int type, int window, bool dataEndable){
         }
         status = recvMessage(sockt);
         cout << "receive status:" << status << endl;
+        cout << "sequence: "<<messages.back().sequence.to_ulong()<<" next: "<<nextSequence<<endl;
         if(status == NOISE){
             continue;
         } else if(status == type) {
-            if(messages.back().sequence.to_ulong() != nextSequence){
+            if(!messages.empty() && (messages.back().sequence.to_ulong() != nextSequence)){
+                messages.pop_back();
                 response.reset();
                 vector<BYTE> val(1,(BYTE)nextSequence);
                 response.setData(val, NACK);
                 shouldSend = true;
-            } else if(window == WAIT_STOP || ((nextSequence % SLIDING) == 0)) {
-                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 {
-                //TODO: treat something?
+                if(window == WAIT_STOP || ((nextSequence % SLIDING) == 0)) {
+                    response.reset();
+                    vector<BYTE> val(1,(BYTE)messages.back().sequence.to_ulong());
+                    response.setData(val, ACK);
+                    shouldSend = true;
+                }
+                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;
+            cout << "ERROR: " << messages.back().getDataAsString() << endl;
             return -1;
         }
-
-        // else if(messages.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: treat error
-        //     break;
-        // }
-        // shouldSend = shouldSend || (frame.size()%window == 0);
     }while(status != end);
+    if(dataEndable){
+        response.reset();
+        vector<BYTE> val(1,(BYTE)messages.back().sequence.to_ulong());
+        response.setData(val, ACK);
+        response.sendMessages(sockt);
+    }
     return 0;
 }
 
diff --git a/definitions.h b/definitions.h
index a5305db8e80d31492227baabe1c443ead7c1a19e..3e5b5399c28e680c3d1e49fa72685acae2a05cbf 100644
--- a/definitions.h
+++ b/definitions.h
@@ -16,7 +16,7 @@ using namespace std;
 //Delimiter indicating beginning of a message
 #define BEGIN 0x7E
 //Socket device
-#define DEVICE "lo"
+#define DEVICE "enp8s2"
 //Message types
 #define NACK 0
 #define ACK 1
diff --git a/dirFunctions.cpp b/dirFunctions.cpp
index d0e7aa4509560a894ee75b0e4ce921724bd2bce2..0952e3100f1ba6bf3aa74a6fa3019d60cda9ba7b 100644
--- a/dirFunctions.cpp
+++ b/dirFunctions.cpp
@@ -1,9 +1,11 @@
 #include <iostream>
+#include <fstream>
 #include <errno.h>
 #include <unistd.h>
 #include <string.h>
 #include <vector>
 #include <stdio.h> //popen
+#include <sys/statvfs.h>
 
 using namespace std;
 
@@ -28,3 +30,28 @@ string ls(string args){
     pclose(lsOut);
     return output;
 }
+
+string getWorkingPath(){
+   char temp[1024];
+   return (getcwd(temp, 1024) ? string(temp) : string(""));
+}
+
+bool hasEnoughSpace(int size){
+    struct statvfs fsData;
+    string path = getWorkingPath();
+    statvfs(path.c_str(), &fsData);
+    int freeSpace = fsData.f_bsize * fsData.f_bfree;
+    return (freeSpace > size);
+}
+
+
+void writeFile(string path, vector<BYTE>data){
+    cout << "path: "<< path<<endl;
+    string strData(data.begin(), data.end());
+    ofstream file(path);
+    if (file.is_open()){
+        file << strData;
+        file.close();
+    }
+    else cout << "Unable to open file";
+}
diff --git a/dirFunctions.h b/dirFunctions.h
index fe120405bd8f732f027633b8b0ad3107c3d8b0a0..a2e37f798836aaee5d0d43b863b758b289f1eaae 100644
--- a/dirFunctions.h
+++ b/dirFunctions.h
@@ -9,4 +9,10 @@ void cd(string path);
 
 string ls(string path);
 
+bool hasEnoughSpace(int size);
+
+string getWorkingPath();
+
+void writeFile(string path, vector<BYTE>data);
+
 #endif
\ No newline at end of file
diff --git a/server.cpp b/server.cpp
index 637f0ce24804343e5cf50193ad847e5a0d3587bc..b2e4325baa614a3e270c63d2f91673bf4ca47d9b 100644
--- a/server.cpp
+++ b/server.cpp
@@ -18,8 +18,7 @@ int main(){
             if(status == CD){
                 cout << "Recebeu CD\n";
                 cd(receiveProtocol.getDataAsString());
-                vector<BYTE> val(1,(BYTE)0);
-                sendProtocol.setData(val, OK);
+                sendProtocol.setData(vector<BYTE>(1,(BYTE)0), OK);
                 sendProtocol.sendMessage(sockt,0);
             }else if(status == LS){
                 cout << "protocol data: " << receiveProtocol.getDataAsString() << endl;
@@ -29,9 +28,34 @@ int main(){
                 sendProtocol.setData(vector<BYTE>(output.begin(), output.end()), OUTPUT);
                 sendProtocol.transmit(sockt, WAIT_STOP);
             }else if(status == PUT){
-                //TODO
+                string fileName = receiveProtocol.getDataAsString();
+                cout << "fileName: " << fileName <<endl;
+                sendProtocol.setData(vector<BYTE>(1,(BYTE)0), OK);
+                sendProtocol.sendMessage(sockt,0);
+                receiveProtocol.reset();
+                receiveProtocol.receive(sockt,SIZE,WAIT_STOP,false);
+                cout << "fileSize: " << receiveProtocol.getDataAsString() <<endl;
+                int fileSize = stoi(receiveProtocol.getDataAsString());
+                sendProtocol.reset();
+                if(hasEnoughSpace(fileSize)){
+                    sendProtocol.setData(vector<BYTE>(1,(BYTE)0), OK);
+                    sendProtocol.sendMessage(sockt,0);
+                }else{
+                    sendProtocol.setData(vector<BYTE>(1,(BYTE)SPACE_ERR), ERROR);
+                    sendProtocol.sendMessage(sockt,0);
+                }
+                receiveProtocol.reset();
+                receiveProtocol.receive(sockt,DATA,SLIDING,true);
+                cout <<"conteudo: "<< receiveProtocol.getDataAsString()<<endl;
+                writeFile(getWorkingPath()+"/"+fileName,receiveProtocol.getData());
+
             }else if(status == GET){
                 //TODO
+            }else if(status == ENDTX){
+                sendProtocol.reset();
+                vector<BYTE> val(1,(BYTE)receiveProtocol.getMessages().back().sequence.to_ulong());
+                sendProtocol.setData(val, ACK);
+                sendProtocol.sendMessages(sockt);
             }
         }catch(char const* strException){
             cout << "Erro:" <<strException <<endl;