diff --git a/Protocol.cpp b/Protocol.cpp
index 1cec1b89241eaa7b4b6179e5e6974f5530239fc8..a376c73336a13a4dc479d8466ee5c888ee8af098 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;
     }
@@ -190,6 +190,7 @@ 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) {
@@ -209,11 +210,16 @@ int Protocol::receive(int sockt, int type, int window, bool dataEndable){
                 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;
         }
     }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/dirFunctions.cpp b/dirFunctions.cpp
index 2845ba91e6cbe51ed3d268fdf179aa7aec5a0a0b..6e050ab38142d470467dee1e405eb69b44829c2a 100644
--- a/dirFunctions.cpp
+++ b/dirFunctions.cpp
@@ -1,4 +1,5 @@
 #include <iostream>
+#include <fstream>
 #include <errno.h>
 #include <unistd.h>
 #include <string.h>
@@ -6,6 +7,7 @@
 #include <stdio.h> //popen
 #include <sys/stat.h>
 #include <fstream>
+#include <sys/statvfs.h>
 
 using namespace std;
 
@@ -31,6 +33,11 @@ string ls(string args){
     return output;
 }
 
+string getWorkingPath(){
+   char temp[1024];
+   return (getcwd(temp, 1024) ? string(temp) : string(""));
+}
+
 bool fexists(string path) {
     struct stat buffer;
     return (stat(path.c_str(), &buffer) == 0);
@@ -40,3 +47,23 @@ int filesize(string path) {
     ifstream in(path, ifstream::ate | ifstream::binary);
     return in.tellg();
 }
+
+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 08832baa03082002b5421f3ce987daa11f881344..3b83f837ff3265baf90a27475bb4a56cac4e754d 100644
--- a/dirFunctions.h
+++ b/dirFunctions.h
@@ -13,4 +13,10 @@ bool fexists(string path);
 
 int filesize(string path);
 
+bool hasEnoughSpace(int size);
+
+string getWorkingPath();
+
+void writeFile(string path, vector<BYTE>data);
+
 #endif
diff --git a/server.cpp b/server.cpp
index 345997c87b21d0d53774516bc0e59948187e81c2..e4cc73c02e60ac9b75d24cc3d8488553064741ce 100644
--- a/server.cpp
+++ b/server.cpp
@@ -19,8 +19,7 @@ int main(){
                 cout << "Recebeu CD\n";
                 cout << "CD: " << receiveProtocol.getDataAsString() << endl;
                 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;
@@ -31,9 +30,34 @@ int main(){
                 sendProtocol.transmit(sockt, WAIT_STOP);
                 cout << "finished transmit" << endl;
             }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;