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#pragma comment(lib, "wsock32.lib")
#include <stdio.h>
#include <windows.h>
#include <Winsock.h>
WSADATA ws;
char buf[10000];
char ficheroA[10000];
void output(char *str)
{
FILE
*fp
= fopen("output.txt", "a+");}
SOCKET Connect(char* ftpname, int port)
{
WSAStartup(0x101, &ws);
// Open up a socket for out TCP/IP session
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
// Set up socket information.
struct sockaddr_in a = {AF_INET, htons(port)};
// Get the ip address of our ftp
struct hostent *h = gethostbyname(ftpname);
a.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)h->h_addr)));
// Actually connect to the server
connect(s, (struct sockaddr *)&a, sizeof(a));
return s;
}
void receiving(SOCKET s, char* string)
{
char aa[1000] = {'/0'};
int ii = recv(s, aa, sizeof(aa), 0);
output(buf);
if(string !=0)
}
void sending(SOCKET s, char* verb)
{
output("Sending: ");
output(buf);
}
int _stdcall WinMain(HINSTANCE i, HINSTANCE j, char* k, int l)
{
//Creacion de socket para conectar con FTP
SOCKET s1 = Connect("ftp.xxxxxxxxxxx.com", 21);
receiving(s1,0);
//Envio de usuario
sending(s1, "USER yyyyyyyyyyyy");
receiving(s1,0);
//Envio de contraseña
sending(s1, "PASS xxxxxxxxxxxxxx");
receiving(s1,0);
//Envio de tipo de archivos que aceptará, en este caso binarios
sending(s1, "TYPE I");
receiving(s1, 0);
char strPasv[1000];
//Enviamos la activación del modo pasivo
sending(s1, "PASV");
receiving(s1, strPasv);
//Parseamos para quedarnos exclusivamente con la IP y el puerto ********************************
//Ejemplo: "227 Entering Passive Mode (127,0,0,1,167,183)"
int cont=0;
int hostFound=0;
int salida=0;
char ipHost[24]="";
while((cont<sizeof(strPasv))&&(!salida))
{
if(strPasv[cont]=='(')
{
hostFound=1;
}
else if(strPasv[cont]==')')
{
salida=1;
}
else if(hostFound)
{
sprintf(ipHost
,"%s%c",ipHost
,strPasv
[cont
]); }
cont++;
}
char *trozos;
//Separamos los trozos por las comas
//Por cada trozo leido, la introduciremos en su correspondiente variable
char ipFTP2[16]="";
int hp=0;
int lp=0;
for(i=0;trozos;i++)
{
//Almacenamos cada trozo en la IP
if(i<16)
{
if(i==0)
{
sprintf(ipFTP2
,"%s%s",ipFTP2
,trozos
); }
else
{
sprintf(ipFTP2
,"%s.%s",ipFTP2
,trozos
); }
}
//Almacenamos el último trozo en el puerto
else if(i>=16)
{
if(i==16)
{
}
else
{
}
}
}
int portFTP2 = (hp*256) + lp;
printf("IP: %s - PASSIVE PORT: %d\n", ipFTP2
, portFTP2
); //Fin del parseador ****************************************************************************
//Creamos segundo socket para conectar a la IP y PUERTO brindados por el server para el envio
SOCKET s2 = Connect(ipFTP2, portFTP2);
receiving(s2,0); //<==== AQUI NO LLEGA A RECIBIR LA CONTESTACION
//Enviamos STOR para crear el fichero en el FTP y comenzar el envio por el socket s2
char strS1[1000];
sending(s1, "STOR c.txt");
receiving(s1, strS1);
//Envio por el segundo socket el contenido del archivo
sending(s2,"estoEsUnEjemploDeContenidoDeArchivo");
receiving(s2,0);
//Cierro socket 2
sending(s2, "QUIT");
//Cierro socket 1
sending(s1, "QUIT");
receiving(s1,0);
return 0;
}
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