Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Shoxsz

Sockets - Erro recv

Mensagens Recomendadas

Shoxsz

Olá pessoal, estava fazendo um programa em C usando sockets para ler um diretorio e enviar ao ciente os arquivos do diretorio, o problema é que no recebimento da mensagem sempre da erro! já peguei alguns exemplos na internet iguais ao meu e eles funcionam perfeitamente bem, mas quando volto pro meu programa, ele nunca recebe a mensagem do cliente:

...
    listen(sock, 10);
    printf("Aguardando conexao...\n");
    if((sockc = accept(sock, (SOCKADDR*)&cliente, &t) == -1))
    {
        perror("accept");
        return 0;
    }
    printf("Cliente conectado!\n");
    while(1)
    {
        b = recv(sockc, diretorio, MAX_DIR, 0);
...

estou fazendo algo de errado no recebimento da mensagem??

Editado por pmg

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Shoxsz

cara, eu sei disso, essa é só a parte para mostrar que eu já fiz até o bind e estou utilizando 2 descritores para os sockets, um pro sevidor e o outro retornado pela função accept

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

cara, eu sei disso, essa é só a parte para mostrar que eu já fiz até o bind e estou utilizando 2 descritores para os sockets, um pro sevidor e o outro retornado pela função accept

pois, mas não apresentaste o código, pois não ?

como sei se está bem ?

como sei que o que está para trás se encontra correcto, e andas a fazer chamadas com um descritor válido ?

do código que vejo, não fazes uma única sequer validação de chamada, por isso só posso assumir que o mesmo não é feito no código não apresentado


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Shoxsz

aqui está o código:

#include <stdio.h>
#include <winsock.h>
#include <dirent.h>
#define MAX_DIR 100
#define PADRAO 4700
#define BYTES_POR_VEZ 500
#define E404 "Diretorio nao encontrado"
#define DIR_OK "Diretorio encontrado"
#define INICIO "inicio"
WSADATA wsa;
SOCKET sock, sockc;
SOCKADDR_IN serv, cliente;
FILE* arq;//Ultimo arquivo encontrado no diretório
DIR* dir;//Diretório principal
DIR* sec;//Diretório que secundário
struct dirent* at;
int ler_diretorio();
int ler_arquivo(char*, int);
int cabecalho(const char*, int);
int tamanho_arquivo();
int main()
{
char diretorio[MAX_DIR], buffer[bYTES_POR_VEZ];
int b;
while(1)
{
 printf("Iniciando servidor...\n");
 if(WSAStartup(MAKEWORD(1, 1), &wsa) == -1)
 {
	 perror("WSAStartup");
	 return 0;
 }
 if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
 {
	 perror("socket");
	 return 0;
 }
 serv.sin_family = AF_INET;
 serv.sin_port = htons(PADRAO);
 serv.sin_addr.s_addr = INADDR_ANY;
 int t = sizeof(serv);
 if(bind(sock, (SOCKADDR*)&serv, t) == -1)
 {
	 perror("bind");
	 return 0;
 }
 listen(sock, 1);
 printf("Aguardando conexao...\n");
 if((sockc = accept(sock, (SOCKADDR*)&cliente, &t) == -1))
 {
	 perror("accept");
	 return 0;
 }
 printf("Cliente conectado!\n");
 while(1)
 {
b = recv(sockc, diretorio, MAX_DIR, 0);
	 if(b < 0)
	 {
		 perror("recv");
		 return 0;
	 }
	 else if(b == 0)
	 {
		 printf("Conexao perdida!\n");
		 return 0;
	 }
	 else
	 {
		 diretorio[b] = '\0';
		 printf("Diretorio para leitura: %s\n", diretorio);
	 }
	 dir = opendir(diretorio);
	 //erro
	 if(dir == NULL)
	 {
		 //Enviar mensagem de erro
		 send(sockc, E404, strlen(E404), 0);
		 printf("%s\n", E404);
		 continue;
	 }
	 //Ler os arquivos do diretório atual
	 while(ler_diretorio() == 1)
	 {
		 //Abrir o arquivo atual
		 arq = fopen(at->d_name, "r");
		 if(arq == NULL)
		 {
			 printf("Falha ao abrir arquivo %s\n", at->d_name);
			 continue;
		 }
		 //Mensagem indicando o inicio de um arquivo
		 if(cabecalho(at->d_name, tamanho_arquivo()) == -1)
		 {
			 printf("Falha ao enviar arquivo %s\n", at->d_name);
			 continue;
		 }
		 //ler arquivo e enviar
		 while(ler_arquivo(buffer, BYTES_POR_VEZ) > 0)
		 {
			 send(sockc, buffer, strlen(buffer), 0);
		 }
		 fclose(arq);
	 }
 }
}
return 0;
}

int ler_diretorio()
{
if((at = readdir(sec)))
 return 1;
return 0;
}
int ler_arquivo(char* buffer, int tam)
{
int i;
for(i = 0; i < tam; i++)
{
 if(!feof(arq))
	 break;
 buffer[i] = fgetc(arq);
}
buffer[i] = '\0';
return i;
}
///Enviar o cabecalho indicando inicio de arquivo para o cliente
int cabecalho(const char* arquivo, int tam)
{
char msg[strlen(arquivo) + strlen(INICIO) + 2];
sprintf(msg, "%s %s", INICIO, arquivo);
if(send(sockc, msg, strlen(msg), 0) <= 0)
 return -1;
itoa(tam, msg, 10);
//Enviar o tamanho do arquivo a ser enviado
if(send(sockc, msg, strlen(msg), 0) <= 0)
 return -1;
return 1;
}
int tamanho_arquivo()
{
fseek(arq, 0, SEEK_END);
int t = ftell(arq);
rewind(arq);
return t;
}

Editado por Shoxsz

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

o código parece correcto, mas para dançar o tango, são necessários 2

e o código do cliente ?


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Shoxsz

aqui esta:

#include <stdio.h>
#include <winsock.h>
#define MASTER "192.168.1.50"
#define MAX_DIR 100
#define PADRAO 4700
#define BYTES_POR_VEZ 500
#define E404 "Diretorio nao encontrado"
#define DIR_OK "Diretorio encontrado"
#define INICIO "inicio"
WSADATA wsa;
SOCKET sock;
SOCKADDR_IN info;
int main()
{
   char ip[16];
   char diretorio[MAX_DIR];
   char buffer[bYTES_POR_VEZ];
   if(WSAStartup(MAKEWORD(2, 2), &wsa) == -1)
   {
       perror("WSAStartup");
       return 0;
   }
   if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
   {
       perror("socket");
       return 0;
   }
   info.sin_family = AF_INET;
   info.sin_port = htons(PADRAO);
   printf("IP para conexao: ");
   fflush(stdin);
   scanf("%s", ip);
   ip[16] = '\0';
   if(strcmp(ip, "MASTER") == 0)
       strcpy(ip, MASTER);
   info.sin_addr.s_addr = inet_addr(ip);
   //Conectar
   if(connect(sock, (SOCKADDR*)&info, sizeof(info)) == -1)
   {
       perror("connect");
       return 0;
   }
   printf("Conectado!\n");
   int ok=0;
   do
   {
       printf("Diretorio a ser transferido: ");
       fflush(stdin);
       scanf("%s", diretorio);
       if(strlen(diretorio) > MAX_DIR)
       {
           printf("Nome do diretorio muito grande!\n");
       }
       ok = 1;
   }while(!ok);
   printf("Enviando requisicao de diretorio\n");
   if(send(sock, diretorio, strlen(diretorio), 0) <= 0)
   {
       printf("Falha ao enviar diretorio!\n");
       perror("send");
       return 0;
   }
   printf("Requisicao enviada!");
   printf("Aguardando resposta...\n");
   //teste para ver como a resposta chega
   while(recv(sock, buffer, BYTES_POR_VEZ, 0) > 0)
   {
       printf("%s", buffer);
   }
   return 0;
}

Editado por brunoais
geshi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pikax

Porque que estas a usar versoes diferentes de sockets??

Usa portas diferentes para o cliente e para o server


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Shoxsz

a sim, as versões eu troquei pra testar a diferença, mas ainda sim se forem iguais dava erro, mas as portas são as mesmas, a constante definida la em cima-> PADRAO(4700)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

então tens ai o problema ... as aplicações necessitam de correr em portas diferentes

é normal deixar o sistema operativo deixar escolher uma porta aleatória para o cliente, visto este não necessitar de uma porta específica


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Shoxsz

elas devem usar a mesma porta para comunicação, eu troquei as portas e ele nem chegam a se conectar, o meu problema é na leitura dos dados.

Editado por Shoxsz

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

elas devem usar a mesma porta para comunicação, eu troquei as portas e ele nem chegam a se conectar, o meu problema é na leitura dos dados.

errado, não podes ter duas aplicações penduradas na mesma porta ...

se não obtiveste ligação com a alteração é porque usaste uma porta já em uso


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Shoxsz

co um port scanner encontrei dus portas que não estavam em uso, tentei conectar por elas, mas não funcionou, as portas são:

39040 para o servidor e 39039 para o cliente

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

estive a ver melhor o teu código ...

à definição PADRAO que tens tem significados diferentes nas duas aplicações

- servidor : porta em que o servidor se encontra à escuta

- cliente : porta do servidor

conclusão : sim, necessitas de ter os dois valores iguais


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.