Ver Mensaje Individual
  #7 (permalink)  
Antiguo 30/08/2013, 02:34
Avatar de jja
jja
 
Fecha de Ingreso: diciembre-2010
Ubicación: BCN
Mensajes: 47
Antigüedad: 13 años, 10 meses
Puntos: 0
Respuesta: Problema con cliente FTP en C

Buenas, muchas gracias por el esfuerzo, me estás ayudando mucho. He seguido al pie de la letra lo que me comentas, he parseado la respuesta de PASV, y he separado la IP que me devuelve el servidor, y he generado el puerto pasivo con hp y lp. Hasta aquí todo correcto. Pero cuando intento conectar un 2º socket a esta IP y PUERTO pasivo, no me responde. Te dejo el código que llevo por si tienes 5 minutos para probarlo. He marcado con una flecha en qué punto se me queda atrancado el programa porque el servidor no me da respuesta:

Código C:
Ver original
  1. #pragma comment(lib, "wsock32.lib")
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <Winsock.h>
  5.  
  6. WSADATA ws;
  7. char buf[10000];
  8. char ficheroA[10000];
  9.  
  10. void output(char *str)
  11. {
  12.       FILE *fp = fopen("output.txt", "a+");
  13.       fprintf(fp, "%s\n", str);
  14.       fclose(fp);
  15. }
  16.  
  17. SOCKET Connect(char* ftpname, int port)
  18. {
  19.       WSAStartup(0x101, &ws);
  20.       // Open up a socket for out TCP/IP session
  21.       SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
  22.       // Set up socket information.
  23.       struct sockaddr_in a = {AF_INET, htons(port)};
  24.       // Get the ip address of our ftp
  25.       struct hostent *h = gethostbyname(ftpname);
  26.       a.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)h->h_addr)));
  27.       // Actually connect to the server
  28.       connect(s, (struct sockaddr *)&a, sizeof(a));
  29.       return s;
  30. }
  31.  
  32. void receiving(SOCKET s, char* string)
  33. {
  34.       char aa[1000] = {'/0'};
  35.       int ii = recv(s, aa, sizeof(aa), 0);
  36.       sprintf(buf, "~%s~", aa);
  37.       output(buf);
  38.       if(string !=0)
  39.             strcpy(string, aa);
  40. }
  41.  
  42. void sending(SOCKET s, char* verb)
  43. {
  44.       strcpy(buf, verb);
  45.       strcat(buf, "\r\n");
  46.       output("Sending: ");
  47.       output(buf);
  48.       send(s, buf, strlen(buf), 0);
  49. }
  50.  
  51. int _stdcall WinMain(HINSTANCE i, HINSTANCE j, char* k, int l)
  52. {
  53.       //Creacion de socket para conectar con FTP
  54.       SOCKET s1 = Connect("ftp.xxxxxxxxxxx.com", 21);
  55.       receiving(s1,0);
  56.  
  57.       //Envio de usuario
  58.       sending(s1, "USER yyyyyyyyyyyy");
  59.       receiving(s1,0);
  60.  
  61.       //Envio de contraseña
  62.       sending(s1, "PASS xxxxxxxxxxxxxx");
  63.       receiving(s1,0);
  64.  
  65.       //Envio de tipo de archivos que aceptará, en este caso binarios
  66.       sending(s1, "TYPE I");
  67.       receiving(s1, 0);
  68.  
  69.       char strPasv[1000];
  70.  
  71.       //Enviamos la activación del modo pasivo
  72.       sending(s1, "PASV");
  73.       receiving(s1, strPasv);
  74.       printf("%s\n",strPasv);
  75.  
  76.       //Parseamos para quedarnos exclusivamente con la IP y el puerto ********************************
  77.       //Ejemplo: "227 Entering Passive Mode (127,0,0,1,167,183)"
  78.       int cont=0;
  79.       int hostFound=0;
  80.       int salida=0;
  81.       char ipHost[24]="";
  82.       while((cont<sizeof(strPasv))&&(!salida))
  83.       {
  84.            if(strPasv[cont]=='(')
  85.            {
  86.                hostFound=1;
  87.            }
  88.            else if(strPasv[cont]==')')
  89.            {
  90.                salida=1;
  91.            }
  92.            else if(hostFound)
  93.            {
  94.                sprintf(ipHost,"%s%c",ipHost,strPasv[cont]);
  95.            }
  96.            cont++;
  97.       }
  98.  
  99.       char *trozos;
  100.  
  101.       //Separamos los trozos por las comas
  102.       trozos = strtok(ipHost,",");
  103.  
  104.       //Por cada trozo leido, la introduciremos en su correspondiente variable
  105.       char ipFTP2[16]="";
  106.       int hp=0;
  107.       int lp=0;
  108.       for(i=0;trozos;i++)
  109.       {
  110.             //Almacenamos cada trozo en la IP
  111.             if(i<16)
  112.             {
  113.                 if(i==0)
  114.                 {
  115.                     sprintf(ipFTP2,"%s%s",ipFTP2,trozos);
  116.                 }
  117.                 else
  118.                 {
  119.                     sprintf(ipFTP2,"%s.%s",ipFTP2,trozos);
  120.                 }
  121.             }
  122.             //Almacenamos el último trozo en el puerto
  123.             else if(i>=16)
  124.             {
  125.                 if(i==16)
  126.                 {
  127.                     hp=atoi(trozos);
  128.                 }
  129.                 else
  130.                 {
  131.                     lp=atoi(trozos);
  132.                 }
  133.  
  134.             }
  135.             trozos=strtok(0,",");
  136.       }
  137.       int portFTP2 = (hp*256) + lp;
  138.       printf("IP: %s - PASSIVE PORT: %d\n", ipFTP2, portFTP2);
  139.       //Fin del parseador ****************************************************************************
  140.  
  141.       //Creamos segundo socket para conectar a la IP y PUERTO brindados por el server para el envio
  142.       SOCKET s2 = Connect(ipFTP2, portFTP2);
  143.       receiving(s2,0);  //<==== AQUI NO LLEGA A RECIBIR LA CONTESTACION
  144.  
  145.       //Enviamos STOR para crear el fichero en el FTP y comenzar el envio por el socket s2
  146.       char strS1[1000];
  147.       sending(s1, "STOR c.txt");
  148.       receiving(s1, strS1);
  149.       printf("%s\n",strS1);
  150.  
  151.       //Envio por el segundo socket el contenido del archivo
  152.       sending(s2,"estoEsUnEjemploDeContenidoDeArchivo");
  153.       receiving(s2,0);
  154.      
  155.       //Cierro socket 2
  156.       sending(s2, "QUIT");
  157.  
  158.       //Cierro socket 1
  159.       sending(s1, "QUIT");
  160.       receiving(s1,0);
  161.       return 0;
  162. }

He quitado la parte del programa que parsea el fichero para simplificar, y envio por el momento ula cadena estoEsUnEjemploDeContenidoDeArchivo.

Seguramente que es una chorrada en lo que me falla, pero estoy atascado y ya no veo

1000 gracias
__________________
El supremo arte de la guerra es someter al enemigo sin luchar.

Sun Tzu