Arquivos binários e sockets C++

1. Arquivos binários e sockets C++

Paulo
paulo_moc

(usa Ubuntu)

Enviado em 09/02/2014 - 14:18h

Olá pessoal, um tempo atras fiz um programa para troca de arquivos servidor->cliente, ele funcionava legal, agora fui tentar transmitir um arquivo .zip e um .exe, mas ele só transmite uma parte, no arquivo .exe ele transimitiu apenas 400 bytes e parou e no .zip ele transmitiu 16kb e trava, então aumentei o fluxo de bytes para 4000, então ele foi até 200kb e travou, aumentei para 40k e só foi até 100kb, já até tentei colocar um delay de 1000ms no servidor para não sobrecarregar o buffer do cliente(não sei muito bem como funcionam as coisas nesse nivel), mas a dúvida é essa: porque essa atitude diferente com dados binários? no final das contas não são só bytes(bits)? tipo ctrl+c e ctrl+v? tá legal, agora ta na hora do código:

servidor:

#include <string>
#include <stdio.h>
#include <socket.hpp>
#include <windows.h>

using namespace SOCKETS_P;

const std::string arquivo("tinyxml2.h");

int main()
{
uint32_t size;
int read;
char buff[40000];
FILE* file;
TCPServer server;
TCPClient* client;

file = fopen(arquivo.c_str(), "rb");

if(!file)
{
perror("fopen");
return 0;
}

fseek(file, 0,SEEK_END);
size = ftell(file);
rewind(file);

std::cout<<"Tamanho do arquivo(bytes): "<<size<<std::endl;

try
{
Socket::initWinApiSock();
server.setMaxConnections(5);
server.start(5050);

std::cout<<"Aguardando conexao..."<<std::endl;
while(!server.canRead())
Sleep(1000);

server.acceptConnection();
client = server.getLastClient();

std::cout<<"Enviando arquivo..."<<std::endl;

//envia o tamanho do arquivo
client->sendMessage(&size, sizeof(uint32_t));

while(!feof(file))
{
read = fread(buff, sizeof(char), 40000, file);
client->sendMessage(buff, read);
}
std::cout<<"Arquivo enviado."<<std::endl;

//Aguarda fim da conexão pelo cliente.
client->readMessage(buff, 1);

Socket::shutDownWinApiSock();
}
catch(Exception ex)
{
if(ex.getErrorId() == END_CONNECTION)
std::cout<<"Conexão encerrada."<<std::endl;
else
std::cout<<"Error: "<<ex.getErrorCause()<<std::endl;
}

fclose(file);

return 0;
}



Cliente:

#include <string>
#include <stdio.h>
#include <socket.hpp>
#include <windows.h>

using namespace SOCKETS_P;

const std::string arquivo("tinyxml2.h");

int main(int argc, char* argv[])
{
InternetAddress addr(AF_INET, "127.0.0.1", 5050);
uint32_t downloaded = 0, size = 0;
std::string read;
FILE* file;
TCPClient client;

if(argc > 1)
addr.setHost(argv[1]);

file = fopen(arquivo.c_str(), "wb");

if(!file)
{
perror("fopen");
return 0;
}

try
{
Socket::initWinApiSock();

client.connectTo(addr);

std::cout<<"Conectado ao servidor("<<addr.getIp()<<")."<<std::endl;
std::cout<<"Aguardando arquivo!"<<std::endl;

//O loop fica disposto desta maneira para caso o servidor falhe e atrase no envio de mensagens, o cliente continue esperando pelos dados
//!obs: usar contador para time_out.
while(!client.canRead())
{
Sleep(1000);

while(client.canRead())
{
if(!size)
{
client.readMessage(&size, sizeof(uint32_t));
std::cout<<"Tamanho do arquivo(bytes): "<<size<<std::endl;
}
else
{
downloaded += client.readMessage(read, 40000);
fwrite(read.c_str(), read.size()*sizeof(char), 1, file);
}
}

if(downloaded == size)
break;
}
std::cout<<"Arquivo baixado!"<<std::endl;

Socket::shutDownWinApiSock();
}
catch(Exception ex)
{
std::cout<<"Error: "<<strerror(ex.getErrorId())<<std::endl;
}

fclose(file);

return 0;
}



se alguém puder ajudar eu agradeço. :s


  






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts