Underc0de

Foros Generales => Dudas y pedidos generales => Mensaje iniciado por: proxy_lainux en Agosto 01, 2016, 11:45:42 PM

Título: [SOLUCIONADO] Ayuda con código para transferencia de archivos en C
Publicado por: proxy_lainux en Agosto 01, 2016, 11:45:42 PM
Hola

No sé si mi pregunta va en esta zona, pero bueno, espero no poner desorden.

Estaba intentando hacer un programa que me realice una transferencia de archivos basado en C en linux, después de analizar el código, no logro hacerlo funcionar, ya que lo único que logro mandar es un archivo txt e incompleto, y los demás archivos no los logro mandar correctamente.

Espero haya alguien aquí que me pueda ayudar revisando lo que hice y espero me pueda ayudar diciendome que estoy haciendo mal. Hace unos años lo intenté y logré hacerlo funcionar, pero perdí el código y ahora no recuerdo que hice, pero la idea de como lo inicié aún la recuerdo, sin embargo, no logro entender que estoy haciendo mal esta vez.

Dejaré el código, solo espero sea entendible ya que moví varias cosas para hacerlo funcionar.

Servidor

#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>


int main(){

int sockfd, bytenumero;
struct sockaddr_in re;
int sin_size, confd;
long bff, bfin, erecv;
char buf[1024];

sockfd = socket(AF_INET, SOCK_STREAM, 0);

re.sin_family = AF_INET;
re.sin_port = htons(33371);
re.sin_addr.s_addr = INADDR_ANY;
memset(re.sin_zero, 0, 8);

bind(sockfd, (struct sockaddr*)&re, sizeof(struct sockaddr));

sin_size = sizeof(struct sockaddr_in);

listen(sockfd, 10);

sockfd = accept(sockfd, (struct sockaddr *)&re, &sin_size);

recv(sockfd, (char*)bff, sizeof(long), 0);
bfin = ntohl(*((long*)bff));

send(sockfd, "listo", 5, 0);

printf("%d", bfin);

FILE *flito = fopen("/home/grimoire/ko.txt", "wb");

erecv = 0;
bytenumero = 0;

while(erecv < bfin){
   
    bytenumero = recv(sockfd, buf, sizeof(buf), 0);
    fwrite(buf, 1, bytenumero, flito);
   
    erecv = erecv + bytenumero;
    printf("%d", erecv);
   
}


fclose(flito);
close(sockfd);

return 0;

}


Cliente

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>


int main(){


int leido;
int sockfd, ienv;
long siz, zout;
struct hostent *he;
struct sockaddr_in t_add;
FILE *pfile, *flista;
char bff[5];
char bufer[1024];

he = gethostbyname("127.0.0.1");

sockfd = socket(AF_INET, SOCK_STREAM, 0);

t_add.sin_family = AF_INET;
t_add.sin_port = htons(33371);
t_add.sin_addr = *((struct in_addr*)he->h_addr);
memset(t_add.sin_zero,0, 8);


  connect(sockfd, (struct sockaddr*)&t_add, sizeof(struct sockaddr));
 
  pfile = fopen("/home/grimoire/korn.txt", "rb");
  fseek(pfile, 0, SEEK_END);
  siz = ftell(pfile);
  rewind(pfile);
 
  zout = htonl(siz);
 
  printf("%ld", siz);

  send(sockfd, (char*)&zout, sizeof(zout), 0);
 
  recv(sockfd, bff, sizeof(bff), 0);
 
  printf("\n%s\n", bff);
 
  ienv = 0;
  leido = 0;
 
  if(flista != NULL)
 
  while(!feof(pfile)){
   
    leido = fread(bufer, 1, sizeof(bufer), pfile);
    send(sockfd, bufer, leido, 0);
    ienv = ienv + leido;
   
    printf("%d", ienv);
   
  }
 
 
  fclose(pfile);
  close(sockfd);
 
  return 0;

}



Título: Re:Ayuda con código para transferencia de archivos en C
Publicado por: grep en Agosto 02, 2016, 04:20:41 AM
Hola,

voy a remarcar secciones puntuales sólo para que el código funcione.

Comenzando con el cliente,

veo que tienes la siguiente línea:

zout = htonl(siz);

No veo necesario ningún byte ordering más que el de tu máquina. Esto me lleva a borrar esta línea y cambiar el código de send:


// send(sockfd, (char*)&zout, sizeof(zout), 0);
send(sockfd, &siz, sizeof siz, 0);


Finalmente veo que tienes esta línea que no le veo utilidad alguna:


if(flista != NULL) // debes comentar o borrar esta línea



Ahora con el server,

debes corregir tu primer llamada a recv():


// recv(sockfd, (char*)bff, sizeof(long), 0);
recv(sockfd, &bff, sizeof(long), 0);


Además no veo necesario realizar el byte ordering, el cual se encuentra en la asignación a la variable bfin:

bfin = ntohl(*((long*)bff)); // debes comentar o borrar esta línea

En consecuencia debes cambiar las líneas en donde utilizas bfin:


// printf("%d", bfin);
printf("%d", bff);

.
.
.

// while(erecv < bfin){
while(erecv < bff) {



Saludos
Título: Re:Ayuda con código para transferencia de archivos en C
Publicado por: proxy_lainux en Agosto 02, 2016, 04:41:10 PM
Gracias, ah funcionado.

No tenía idea de que htonl se usara para ordenar bytes en el network, yo creía que era para pasar variables long, en este caso pasar el long de la variable donde guarde el tamaño del archivo. pero efectivamente lo quite como mencionas e igual recibí el tamaño del archivo.

Pero ya funciona, gracias por la ayuda :)