diff --git a/headers/client.h b/headers/client.h
index a1079f1bff15ed3d2ea5d35f2f7758a434f62f4f..bf547f40ad17fe6d4a5b5aebf8afa1eb5a3140bc 100644
--- a/headers/client.h
+++ b/headers/client.h
@@ -16,15 +16,13 @@
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
-
+#include <sys/stat.h>
 #include <arpa/inet.h>
 
 // include local
 #include "conexao.h"
 #include "frame.h"
 
-#define NUM_RETRIES 100
-
 vector<string> CMD_HELP = {"H",  "help",  "-h",    "HELP", "Help",
                            "-H", "ajuda", "Ajuda", "AJUDA"};
 vector<string> CMD_EXIT = {"exit", "-e",   "EXIT", "Exit",
@@ -51,7 +49,13 @@ private:
   char string_cmd(string str);
   void print_help();
   bool verify_ack(frame *received, frame *sent);
+  frame *receive_ack(frame *f);
   vector<frame *> create_frames(vector<char> data, int type);
+  int send_frame_socket(frame *f);
+  int start_transmission();
+  int end_transmission();
+  string calc_file_size(string fileName);
+  vector<char> read_file(string fileName);
 
 public:
   // --------- Dados ---------- //
@@ -66,6 +70,86 @@ public:
 
 // ------------------------------ PRIVATE --------------------------------- //
 
+// Verifica se recebeu um ack valido
+frame *client::receive_ack(frame *f)
+{
+  frame *ack_res = NULL;
+
+  // se recebemos algo, e NÃO ẽ o ACK que estamos
+  // esperando, continuamos tentando receber
+  do {
+    ack_res = socket->receive_frame();
+    if (ack_res->get_tipo() == ERRO) 
+    { 
+      cout << "Espaco insulficiente no destino\n";
+      return NULL;
+    }
+
+  } while (
+    ack_res &&
+    !(verify_ack(ack_res, f) &&
+      ack_res->get_dado()[0] == f->get_seq())
+  );
+
+  return ack_res;
+}
+
+// Solicita ao socket que envie um frame
+int client::send_frame_socket(frame *f)
+{
+  // Fica tentando enviar o frame até receber o ack
+  frame* ack_res = NULL;
+  int retries = 0;
+  do {
+    // envia um frame da fila
+    socket->send_frame(f);
+    ack_res = receive_ack(f);
+    retries++;
+
+  } while (ack_res == NULL && retries < NUM_RETRIES);
+
+  if (ack_res == NULL && retries == NUM_RETRIES) {
+    cout << "Desisti de enviar\n";
+    return 0;
+  }
+
+  cout << "\tACK recebido:\n";
+  ack_res->imprime(HEX);
+  return 1;
+}
+
+// Inicia a transmissao com o servidor
+int client::start_transmission()
+{
+  cout << "\tIniciando transmissao\n";
+  frame *ini = new frame(INIT, 0, vector<char>(1,0));
+  int enviado = send_frame_socket(ini);
+  if ( !enviado )
+  {
+    cout << "\tFalha ao iniciar a transmissao\n";
+    return 0;
+  }
+
+  cout << "\tTransmissao iniciada com sucesso\n";
+  return 1;
+}
+
+// Encerra a transmissao com o servidor
+int client::end_transmission()
+{
+  cout << "\tEncerrando a transmissao\n";
+  frame *end= new frame(FIMT, 0, vector<char>(1,0));
+  int enviado = send_frame_socket(end);
+  if ( !enviado )
+  {
+    cout << "\tFalha ao encerrar a transmissao\n";
+    return 0;
+  }
+
+  cout << "\tTransmissao encerrada com sucesso\n";
+  return 1;
+}
+
 /**
  * @brief Send a list of frames through the socket
  *
@@ -73,6 +157,7 @@ public:
  * @return int
  */
 int client::send_frames(vector<frame *> frames) {
+  if ( !start_transmission() ) { return 0; }
 
   // Envia um frame por vez
   for (size_t i = 0; i < frames.size(); i++) {
@@ -80,35 +165,18 @@ int client::send_frames(vector<frame *> frames) {
     cout << "\tEnviando frame\n";
     frames[i]->imprime(DEC);
 
-    int retries = 0;
-
-    // Fica tentando enviar o frame até receber o ack
-    frame* ack_res = NULL;
-    do {
-      // envia um frame da fila
-      socket->send_frame(frames[i]);
-      retries++;
-
-      // se recebemos algo, e NÃO ẽ o ACK que estamos
-      // esperando, continuamos tentando receber
-      do {
-        ack_res = socket->receive_frame();
-      } while (
-        ack_res &&
-        !(verify_ack(ack_res, frames[i]) &&
-          ack_res->get_seq() == frames[i]->get_seq())
-      );
-    } while (ack_res == NULL && retries < NUM_RETRIES);
-
-    if (ack_res == NULL && retries == NUM_RETRIES) {
-      cout << "Desisti de enviar\n";
+    int enviado = send_frame_socket(frames[i]);
+    if ( !enviado ) 
+    {
+      cout << "\tFalha ao enviar o frame\n";
       return 0;
     }
 
     cout << "\tFrame enviado com sucesso\n";
   }
 
-  cout << "Terminou de enviar todos os frames\n";
+  if ( !end_transmission() ) { return 0; }
+  cout << "\tTerminou de enviar todos os frames\n";
   return 1;
 }
 
@@ -122,15 +190,7 @@ int client::send_frames(vector<frame *> frames) {
  * @return false
  */
 bool client::verify_ack(frame *received, frame *sent) {
-
-   cout << "Verificando ack\nReceived:\n";
-   received->imprime(HEX);
-   cout << "Sent:\n";
-   sent->imprime(HEX);
-
-  return (
-      received->get_tipo() == ACK                     && 
-      received->chk_crc8());
+  return ( received->get_tipo() == ACK && received->chk_crc8());
 }
 
 /**
@@ -148,18 +208,75 @@ int client::send_message(vector<char> data, int type) {
   return send_frames(frames);
 }
 
+string client::calc_file_size(string fileName)
+{
+  struct stat buffer;
+  stat(fileName.c_str(), &buffer);
+  int fileSize = buffer.st_size;
+
+  return to_string(fileSize);
+}
+
+vector<char> client::read_file(string fileName)
+{
+  fstream file;
+  file.open(fileName, ios::in); 
+
+  if (!file) {
+    cout << "Arquivo inexistente. Operacao abortada\n";
+    return vector<char>();
+  }
+  
+  string teste;
+  vector<char> fileData;
+  char c;
+  while ( (file.get(c), file.eof() == false) )
+  {
+    fileData.push_back(c);
+    teste.push_back(c);
+  }
+
+  file.close();
+  cout << "vetor criado: " << teste << "\n";
+  return fileData;
+}
+
 /**
  * @brief Send a file through the socket
  *
  */
 void client::send_file() {
-  cout << "Enviando arquivo\n";
   string fileName;
-  cout << "Digite o nome do arquivo:\n";
-  getline(cin, fileName);
+  do {
+    cout << "Digite o nome do arquivo(maximo de " << TAM_DADOS << " char):\n";
+    getline(cin, fileName);
+  } while ( fileName.size() > TAM_DADOS );
+
+  // Envia o primeiro frame com o tamanho do arquivo
+  string fileSize = calc_file_size(fileName);
+  cout << "Tamanho do arquivo: " << fileSize << "\n";
+  cout << "Enviando tamanho do arquivo\n";
+  if (!send_message(vector<char>(fileSize.begin(), fileSize.end()), MIDIA))
+  {
+    cout << "Limite de timout, arquivo nao foi enviado\n";
+    return;
+  }
 
+  // Envia o segundo frame com o nome do arquivo
+  cout << "Enviando nome do arquivo\n";
   if (!send_message(vector<char>(fileName.begin(), fileName.end()), MIDIA))
+  {
     cout << "Limite de timout, arquivo nao foi enviado\n";
+    return;
+  }
+
+  cout << "Enviando arquivo\n";
+  vector<char> file = read_file(fileName);
+  if (file.empty() || !send_message(file, DADOS))
+  {
+    cout << "Limite de timout, arquivo nao foi enviado\n";
+    return;
+  }
 
   else
     cout << "Arquivo enviado com sucesso\n";
diff --git a/headers/conexao.h b/headers/conexao.h
index 7be294023ab5a1edf028a5bf12610ee722d6d9db..f736ce341e23eb6cd32d51f1397d6882a89c79ba 100644
--- a/headers/conexao.h
+++ b/headers/conexao.h
@@ -24,6 +24,7 @@
 using namespace std;
 
 #define BYTE "%02x"
+#define NUM_RETRIES 100
 
 class conexao {
 private:
diff --git a/headers/server.h b/headers/server.h
index 6a38d155940c027c65a90a67d6becc3663a3b760..085a75334f38e38269221604ec3b8ce024d972e5 100644
--- a/headers/server.h
+++ b/headers/server.h
@@ -38,6 +38,11 @@ private:
   // ---------- Funcoes -------- //
   int send_nack(frame *fReceive);
   int send_ack(frame *fReceive);
+  void send_confirm(frame *fReceive);
+  void receive_text(frame *f);
+  frame *receive_frame_socket();
+  int receive_valid_frame(frame **f);
+  void start_receveing_message();
 
 public:
   // ------- Construtores ------ //
@@ -59,8 +64,9 @@ int server::send_ack(frame *fReceive) {
   frame *ack = new frame();
 
   ack->set_tipo(ACK);
-  ack->set_dado(vector<char>(fReceive->get_dado(), fReceive->get_dado()+fReceive->get_tam()));
-  ack->set_seq(fReceive->get_seq());
+  vector<char> seq;
+  seq.push_back(char(fReceive->get_seq()));
+  ack->set_dado(seq);
 
   int ackSent = 0;
   ackSent = socket->send_frame(ack);
@@ -81,8 +87,9 @@ int server::send_nack(frame *fReceive) {
   frame *nack = new frame();
 
   nack->set_tipo(NACK);
-  nack->set_dado(vector<char>(fReceive->get_dado(), fReceive->get_dado()+fReceive->get_tam()));
-  nack->set_seq(fReceive->get_seq());
+  vector<char> seq;
+  seq.push_back(char(fReceive->get_seq()));
+  nack->set_dado(seq);
 
   int nackSent = 0;
   nackSent = socket->send_frame(nack);
@@ -92,37 +99,112 @@ int server::send_nack(frame *fReceive) {
   return nackSent;
 }
 
+// Recebe uma mensagem em forma de texto
+void server::receive_text(frame *f)
+{
+  string textoReceive;
+  textoReceive.append(f->get_dado());
+  int lastSeq = f->get_seq();
+  
+  do {
+    if ( !receive_valid_frame(&f) ) { continue; }
+    if ( f->get_tipo() != TEXTO ) { continue; }
+    if ( f->get_seq() == lastSeq) { continue; }
+    
+    lastSeq = f->get_seq();
+    textoReceive.append(f->get_dado());
+
+  } while ( f->get_tipo() != FIMT );
+
+  cout << "Mensagem recebida: " << textoReceive << "\n";
+}
 
-// ------------------------------- PUBLIC --------------------------------- //
+// Recebe o primeiro frame do cliente
+frame *server::receive_frame_socket()
+{
+  frame *fReceive;
+  int retries = 0;
 
-/**
- * @brief function that runs the server thread and receives the frames
- *
- */
+  do
+  {
+    retries++;
+    if ( ! (fReceive = socket->receive_frame()) ) { continue; }
+  } while ( fReceive == NULL && retries < NUM_RETRIES );
 
-// lock the thread with mutex
-void server::run() {
+  if ( fReceive == NULL && retries == NUM_RETRIES ) {
+    cout << "Desisti de receber o frame\n";
+    return NULL;
+  }
+
+  return fReceive;
+}
+
+int server::receive_valid_frame(frame **f)
+{
+  int crc8;
+
+  do {
+    // Se nao conseguir receber o frame, mata a comunicacao
+    *f = receive_frame_socket();
+    if ( *f == NULL ) { return 0; }
+
+    // Avisa o cliente se nao conseguiu receber o frame
+    crc8 = (*f)->chk_crc8();
+    if ( crc8 ) { send_ack(*f); break; }
+    send_nack(*f);
 
+  } while ( !crc8 );
+
+  return 1;
+}
+
+void server::start_receveing_message()
+{
+  int endTransmission = 0;
+
+  do { 
+    frame *f = receive_frame_socket();
+    if ( !f ) { return; } 
+    int frameType = f->get_tipo();
+
+    switch (frameType)
+    {
+      case TEXTO:
+        receive_text(f);
+        endTransmission = 1;
+        break;
+
+      case MIDIA:
+        break;
+
+      default:
+        break;
+    }
+  } while ( !endTransmission );
+}
+
+
+// ------------------------------- PUBLIC --------------------------------- //
+
+void server::run() {
   while (true) {
-    frame *fReceive;
 
     /*-- listening local ip and waiting for messages --*/
     /*-- ignore if the package is not valid          --*/
+    frame *fReceive;
     if ( ! (fReceive = socket->receive_frame()) ) { continue; }
+
     cout << "Frame recebido:" << endl;
     fReceive->imprime(HEX);
 
-    /*-- if frame is an ACK or NACK, it ignores it --*/
-    bool sendAck = fReceive->chk_crc8() && (fReceive->get_tipo() != ACK) &&
-                   (fReceive->get_tipo() != NACK);
-    bool sendNack = !fReceive->chk_crc8() && fReceive->get_tipo() != ACK &&
-                    fReceive->get_tipo() != NACK;
-
-    /*-- checking crc and sending ack or nack --*/
-    if (sendAck)
-      send_ack(fReceive);
-    else if (sendNack)
-      send_nack(fReceive);
+    // Verifica se o frame eh de inicio de transmissao e se nao veio com erro
+    int frameType = fReceive->get_tipo();
+    if ( frameType != INIT ) { continue; }
+    
+    if ( !fReceive->chk_crc8() ) { send_nack(fReceive); continue; }
+
+    send_ack(fReceive);
+    start_receveing_message();
   }
 }
 
diff --git a/src/exemplo.cpp b/src/exemplo.cpp
index 400e8f3500a799bd32d26c6ac90ab73255600dc0..cbad342a25a068ad22e2a1c52c767a21a506eeb9 100644
--- a/src/exemplo.cpp
+++ b/src/exemplo.cpp
@@ -25,13 +25,9 @@ int get_status( char *argv )
 int main(int argc, char *argv[]) {
 
   gen_crc8_table();
-<<<<<<< HEAD:exemplo.cpp
   char* device = argv[2];
   cout << "Device: " << device << endl;
   conexao socket(device);
-=======
-  conexao socket((char *)argv[2]);
->>>>>>> 80e7f477d4253b6d77bf36c80fb004480000a16a:src/exemplo.cpp
 
   int status = get_status(argv[1]);
   switch ( status )
diff --git a/todo.txt b/todo.txt
index d702e4fbe5ffd0a6a6f3c1d7aa288eb65eb90a00..f1653f25511af31b9fa71c051f565ea5eb8bf7cd 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,8 +1,8 @@
 -> Ver se os frames que estao vindo sao arquivos e juntar eles no arquivo
 
--> Juntar todos os frames num so para mensagens de mais de dois frames
+-> Testar tamanho antes de enviar o arquivo
 
--> Fazer o close_connection
+-> Arrumar a interface
 
 -> Merge correcao de erro
   -> Enviar arquivo correcao de erros
@@ -14,14 +14,8 @@
 
 -> Merge log
 
--> Organizar header/src diretorios
-
 -> Adicionar coisas no log
 
--> Testar tamanho antes de enviar o arquivo
-
--> Arrumar a interface
-
 -> Polling para enviar/receber (encerrar comunicacao/esperar/trocar)
 
 -> Relatorio