Discussion:
TRANSFERENCIA FICHEROS EN CLIENTE FTP
(demasiado antiguo para responder)
aioritos
2005-06-23 11:51:13 UTC
Permalink
HOLA.

ESPERO QUE ALGUIEN PUEDA AYUDARME CON ESTO.

ESTOY HACIENDO UN CLIENTE FTP. DE MOMENTO LA CONEXION LA REALIZO EN TCP
Y ME VA BIEN TODO. (usuario contraseña ,etc)

LOS PROBLEMAS ME SURGEN A LA HORA DE ENVIAR UN FICHERO, p.e.
/home/pepe/aqui/hola.txt

TENGO UN SOCKET ABIERTO CON LA CONEXIO, PERO SE SUPONE QUE NECESITO
OTRO PARA ENVIAR LOS DATOS, POR EL PUERTO 20.....
PERO NO ESTOY SEGURO DE ESTO QUE HAGO ....


CREO MI COMANDO STOR CON EL NOMBRE DEL FICHERO REMOTO
ABRO UN NUEVO SOCKET
MI struct sockaddr_in ES IGUAL QUE EN LA CONEXION, PERO EN VEZ DEL
PUERTO 21 ASIGNO EL 20

HAGO UN bind(data_id, (struct sockaddr *) &name, sizeof(struct
sockaddr)); DONDE DATA_ID ES EL IDENTIFICADOR DEL NUEVO SOCKET ABIERTO
Y NAME ES LA struct sockaddr_in

ACONTINUACION ESTO (como basicamente es un copy paste, no se muy bien
explicar.Se supone que el resutado es la direccion IP separada por
comas, y lo que me lia bastante es los dos ultimos, los del puerto)
sprintf(port_name, "PORT %d,%d,%d,%d,%d,%d\r\n",
(host_id & 0x000000FF),
(host_id & 0x0000FF00) >> 8,
(host_id & 0x00FF0000) >> 16,
(host_id & 0xFF000000) >> 24,
(name.sin_port & 0xFF00) >> 8,
(name.sin_port & 0x00FF));
ENVIO EL COMANDO CON SEND Y DESPUES ESTOS
send(control_socket_id, "TYPE I\r\n", 8, 0);
send(control_socket_id, "MODE S\r\n", 8, 0);
HASTA AQUI SE SUPONE QUE ME DICE "successful" pero no debe ir bien pq
se queda colgao en la siguiente instruccion que es :

errorlevel = sizeof(name); /*errorlevel es un int*/
/*aqui no llega la ejecucion. Se para en la anterior*/
stream_id = accept(data_id, (struct sockaddr *) &name,
&errorlevel);





NO SE SI EL PROBLEMA ESTA CLARO PERO TENGO MUXO INTERES EN QUE ALGUIEN
ME AYUDE

GRACIAS!!
Oscar Garcia
2005-06-23 14:16:37 UTC
Permalink
Post by aioritos
ESPERO QUE ALGUIEN PUEDA AYUDARME CON ESTO.
Eso esperamos todos. Pero procura no usar las mayúsculas para escribir
texto normal porque parece que nos estás gritando o bien quieres
resaltar todo el texto que escribes (busca "netiqueta" en google y
verás muchos documentos sobre cómo comportarse en Internet).
Post by aioritos
ESTOY HACIENDO UN CLIENTE FTP. DE MOMENTO LA CONEXION LA REALIZO EN TCP
Y ME VA BIEN TODO. (usuario contraseña ,etc)
LOS PROBLEMAS ME SURGEN A LA HORA DE ENVIAR UN FICHERO, p.e.
/home/pepe/aqui/hola.txt
Veamos...
Post by aioritos
TENGO UN SOCKET ABIERTO CON LA CONEXIO, PERO SE SUPONE QUE NECESITO
OTRO PARA ENVIAR LOS DATOS, POR EL PUERTO 20.....
PERO NO ESTOY SEGURO DE ESTO QUE HAGO ....
No es del todo correcto.

Veo que no vas a usar el modo pasivo, de modo que te explicaré
conforme sea necesario cómo funciona el protocolo FTP.
Post by aioritos
CREO MI COMANDO STOR CON EL NOMBRE DEL FICHERO REMOTO
ABRO UN NUEVO SOCKET
MI struct sockaddr_in ES IGUAL QUE EN LA CONEXION, PERO EN VEZ DEL
PUERTO 21 ASIGNO EL 20
A ver.. el puerto remoto no es el puerto 20, si no el que te diga el
cliente remoto.

Es decir... cuando tú envías el TYPE I y recibes la respuesta (200
Type set to I) tú como cliente debes abrir un socket en el puerto que
desees (no necesariamente el 20 ya que si no eres administrador no
podrás abrir dicho puerto para esperar conexiones). Lo mejor es dejar
al sistema operativo que sea él quien decida qué puerto está libre
para ser usado.
Post by aioritos
HAGO UN bind(data_id, (struct sockaddr *) &name, sizeof(struct
sockaddr)); DONDE DATA_ID ES EL IDENTIFICADOR DEL NUEVO SOCKET ABIERTO
Y NAME ES LA struct sockaddr_in
Entonces le envías los datos (y el puerto) que el sistema operativo
considera que están libres.
Post by aioritos
ACONTINUACION ESTO (como basicamente es un copy paste, no se muy bien
explicar.Se supone que el resutado es la direccion IP separada por
comas, y lo que me lia bastante es los dos ultimos, los del puerto)
sprintf(port_name, "PORT %d,%d,%d,%d,%d,%d\r\n",
(host_id & 0x000000FF),
(host_id & 0x0000FF00) >> 8,
(host_id & 0x00FF0000) >> 16,
(host_id & 0xFF000000) >> 24,
(name.sin_port & 0xFF00) >> 8,
(name.sin_port & 0x00FF));
Correcto, y debes esperar a recibir la confirmación (200 PORT command
sucessful).
Post by aioritos
ENVIO EL COMANDO CON SEND Y DESPUES ESTOS
send(control_socket_id, "TYPE I\r\n", 8, 0);
send(control_socket_id, "MODE S\r\n", 8, 0);
Quizá deberias enviar esto ANTES de solicitar información acerca de la
transferencia. ¿Vas leyendo del socket los valores de retorno de los
comandos? Es especialmente importante para saber el estado de las
comunicaciones.
Post by aioritos
HASTA AQUI SE SUPONE QUE ME DICE "successful" pero no debe ir bien pq
errorlevel = sizeof(name); /*errorlevel es un int*/
/*aqui no llega la ejecucion. Se para en la anterior*/
stream_id = accept(data_id, (struct sockaddr *) &name,
&errorlevel);
No creo que sea problema del sizeof.
Post by aioritos
NO SE SI EL PROBLEMA ESTA CLARO PERO TENGO MUXO INTERES EN QUE ALGUIEN
ME AYUDE
No veo claro el problema porque no tengo el código completo para verlo
desde una perspectiva más amplia.

Antes de nada te recomiendo como lectura obligada el RFC del protocolo
FTP:
http://www.w3.org/Protocols/rfc959/
http://www.w3.org/Protocols/rfc959/4_FileTransfer.html

Por otro lado aquí tienes un resumen de cómo debes hacerlo:

-> simboliza un envio entre de tu cliente al servidor
<- simboliza la recepción de un dato desde el servidor

-> TYPE I
<- 200 type set to I
(innecesario porque es el tipo por defecto de modo de transmisión)
-> MODE S
<- 200 mode set to S
(abrimos el socket a la escucha y leemos los datos que contiene)
-> PORT a,b,c,d,x,y
<- PORT command successful
-> STOR hola.txt
<- 150 Opening BINARY mode data conection for 'hola.txt'
(llegados a este punto debes estar atento porque te llegará una
conexión proveniente del servidor por la que deberás enviar los datos
del archivo)
(en cuanto cierres el socket de datos aparecerá en el de comandos)
<- 226 Transfer complete

NOTA: Si usas un router para acceder a internet nunca te llegará la
conexión externa a no ser que uses un proxy linux con ip_nat_ftp
activado y funcional. En caso de que no dispongas de uno deberás
aprender a usar PASV y su respuesta 227 entering passive mode
(a,b,c,d,x,y) que te será mucho más sencillo de implementar porque la
conexión la abres tú.
Post by aioritos
GRACIAS!!
De nada.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-06-24 08:05:07 UTC
Permalink
Bueno, ante todo, gracias Óscar por responder.
En cuanto a lo de las mayúsculas, bueno ya ves.... jeje

Tus consejos son buenos así que intentaré aplicarlos, y si veo que no
me aclaro y si no te importa,claro , te podría enviar el fuente para
que lo veas más de cerca.

Muchas gracias otra vez.

Saludos
aioritos
2005-06-24 09:14:11 UTC
Permalink
Una cosita más. Si quiero hacer pruebas conectandome conmigo mismo,
necesito el PASV??

Es que cuando lo pruebo me sale el Time Out ... y claro como me has
dicho antes, con PASV abro la conexión yo..
Oscar Garcia
2005-06-24 09:27:13 UTC
Permalink
Post by aioritos
Una cosita más. Si quiero hacer pruebas conectandome conmigo mismo,
necesito el PASV??
El modo PORT o PASV pueden usarse sin problemas con localhost. El
único problema que tienes con PORT es al conectarte con equipos de
Internet usando un servidor para compartir la conexión (ya sea máquina
en linux, windows o un router "hardware") que no esté basado en Linux
o que no soporte "seguimiento de conexiones con nat".
Post by aioritos
Es que cuando lo pruebo me sale el Time Out ... y claro como me has
dicho antes, con PASV abro la conexión yo..
¿Eso te lo pone al usar el modo PORT o PASV?

¿Qué secuencia usas hasta que te da ese error?

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-06-24 09:57:50 UTC
Permalink
bueno ahora mismo el metodo tiene esta forma:

nt create_data_socket(int control_socket_id, char *command)
{
int data_id, /* Socket Number of Data Socket
*/
host_id, /* Information about local sys.
*/
stream_id, /* Socket Number of Data Socket
*/
errorlevel; /* General purpose return codes
*/
char port_name[BUFFER];/* Name of the local machine
*/
struct hostent *host_data; /* Container struct host info
*/
struct sockaddr_in name; /* Contain port connect info
*/
static int random_port = 0; /* My way for different port #s
*/



/* Get the name of the local host to get the network information */

if (gethostname(port_name, BUFFER) == -1) {
perror("primero");
return -1;
} else {


send(control_socket_id, "TYPE I\r\n", 8, 0);
get_response(control_socket_id);
send(control_socket_id, "MODE S\r\n", 8, 0);
get_response(control_socket_id);
/*
* Set up the socket, it is assumed that this is going to be an
* AF_INET connection, with a connection based socket.
*/

data_id = socket(AF_INET, SOCK_STREAM, 0);
errorlevel=data_id;
if (errorlevel == -1) {
perror("socket");
printf("Unable to create a socket.%d\n");
}

/*
* Set up the actual connection. Needs a special struct filled
* to contain the host address and the port to connect to.
* If this works, then the connection is completed, and passed
* back to the calling function.
*/
listen(data_id, BUFFER * BUFFER);

/*Pongo a pelo la direccion para hacer pruebas....*/
host_data = gethostbyname("127.0.0.1");
host_id = * ((int *) (host_data->h_addr_list[0]));
name.sin_family = host_data->h_addrtype;
/* Known Issue: This is an arbitrary port assignment, and assumes
* that collisions are infrequent. There is no fallback support
* if the port can not be assigned. I tried some system supported
* assignments, but it would assign ports that were protected which
* this program was not able to access. */
random_port = (random_port + 7) % 500;
name.sin_port = FTP_PORT_DATA + random_port;
name.sin_addr = *((struct in_addr *)host_data->h_addr);

errorlevel = bind(data_id, (struct sockaddr *) &name, sizeof(struct
sockaddr));
if (errorlevel == -1) {
perror("bind");
close(data_id);
return -1;
}

/*
* Create the comma delimited string to use with the PORT command.
*/
sprintf(port_name, "PORT %d,%d,%d,%d,%d,%d\r\n",
(host_id & 0x000000FF),
(host_id & 0x0000FF00) >> 8,
(host_id & 0x00FF0000) >> 16,
(host_id & 0xFF000000) >> 24,
(name.sin_port & 0xFF00) >> 8,
(name.sin_port & 0x00FF));


/*
* Before the connection is completed, the listening buffer size
* is set to the default BUFFER size. And the mode is set to
binary
* and stream. This is done each time a new connection is opened.
*/

send(control_socket_id, port_name, strlen(port_name), 0);
get_response(control_socket_id);

send(control_socket_id, command, strlen(command), 0);
errorlevel = get_response(control_socket_id);

/* A special case to catch in case there is a GET that isn't
there. */

switch (errorlevel) {
case 550 :
destroy_connection(data_id);
return -1;
break;
case 421 :
destroy_connection(data_id);
return -1;
break;
default : /*150*/
puts("\nBieen");
break;
}
/* After using the first socket to make the conneciton: spawn off
* a new socket for the actual data conneciton, and pass this one
* back while destroying the original socket that was used to
* get the data connection.
*/
errorlevel = sizeof(name);
stream_id = accept(data_id, (struct sockaddr *) &name,
&errorlevel);

if (stream_id == -1) {
perror("accept");
return -1;
}
destroy_connection(data_id);

return stream_id;
}
}



Donde:
* command es "STOR hola.txt\r\n"
* BUFFER es 4076
* FTP_PORT_DATA es 12000 (no me digas por que..)

Este código lo saqué de:
http://porter.csres.utexas.edu/work/cs3251/hw4/ftpclient.c

Sólo me estoy centrando en sus funciones de put y get, para
recomponerlas en otro fuente distinto que estoy haciendo.


P.D. : Joe!! Tienes una web mu currada..
aioritos
2005-06-30 08:11:15 UTC
Permalink
Bueno, respondiendo a tu primera pregunta del mensaje anterior,...

¿Eso te lo pone al usar el modo PORT o PASV?

Usando el modo PORT:

200 Type set to I
200 Mode set to S.

200 PORT command successful
421 No Transfer Timeout (300 seconds): closing control connection.

Error: Unable to create data connection.


Saludos
aioritos
2005-07-01 09:08:07 UTC
Permalink
Esperando que algun alma caritativa lea esto, sigo comentando mis
pruebas ...

He probado el modo PASV con identico resultado que el modo PORT:

227 Entering Passive Mode (192,168,0,212,4,154).
421 No Transfer Timeout (300 seconds): closing control connection.

Saludos.
Oscar Garcia
2005-07-01 09:16:45 UTC
Permalink
Post by aioritos
227 Entering Passive Mode (192,168,0,212,4,154).
421 No Transfer Timeout (300 seconds): closing control connection.
¿Tras enviar el comando PASV le envias el GET o el PUT?

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-01 09:40:41 UTC
Permalink
Hola.

Despues de hacer el PASV, hago lo siguiente:

sprintf(command, "STOR %s\r\n", remote_filename);

---Donde remote_filename es hola.txt

send(control_socket_id, command, strlen(command), 0);

---Donde control_socket_id es el identificador del socket de
la conexión (no el de datos)

errorlevel = get_response(control_socket_id);

---Donde get_response devuelve el código de la respuesta del
servidor.

Gracias.
Un Saludo.
Oscar Garcia
2005-07-01 09:57:01 UTC
Permalink
Post by aioritos
sprintf(command, "STOR %s\r\n", remote_filename);
---Donde remote_filename es hola.txt
send(control_socket_id, command, strlen(command), 0);
---Donde control_socket_id es el identificador del socket de
la conexión (no el de datos)
¿Y cuando envias el archivo por el canal de datos?
Post by aioritos
errorlevel = get_response(control_socket_id);
---Donde get_response devuelve el código de la respuesta del
servidor.
Si no envias el archivo entonces en vez de recibir el aviso de que el
archivo ha sido recibido correctamente recibirás un error diciendo que
pasado un tiempo prudencial tú no has enviado nada.
Post by aioritos
Gracias.
De nada.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-01 10:07:55 UTC
Permalink
Creo que tienes toda la razón!

Pero como envío el archivo por el canal ?!?

Uso el comando PUT, enviandolo con send??? o como se hace eso?

Iré probando haber que pasa...

Gracias.
Oscar Garcia
2005-07-01 15:20:32 UTC
Permalink
Post by aioritos
Creo que tienes toda la razón!
Pero como envío el archivo por el canal ?!?
Abrelo con fopen por ejemplo o con open y cada vez que vayas leyendo
un trozo de archivo lo vas enviando. Tras enviar todo el archivo
cierras el socket y punto, deberías recibir al instante la
confirmación de archivo recibido por el socket de control.
Post by aioritos
Uso el comando PUT, enviandolo con send??? o como se hace eso?
Iré probando haber que pasa...
A veces confundo los comandos de un cliente FTP (get, mget, put, mput)
con los comandos del protocolo FTP (RETR y STOR) :P
Post by aioritos
Gracias.
De nada.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-05 11:02:01 UTC
Permalink
Pues no se que es lo que pasa pero sigo sin ser capaz de hacerlo
bien... ahora me pasa:

227 Entering Passive Mode (192,168,0,212,6,169).
200 Type set to I
200 Mode set to S.
Broken pipe


Al enviar la primera lectura del fichero me dice "Broken Pipe"

He comprobado que la longitud esta bien, pero si envío caracter a
caracter igualmente me dice Broken PIpe...

No se que más hacer ya.. te importa que te mande el fichero a ver si
ves alguna solución?
Oscar Garcia
2005-07-05 12:05:30 UTC
Permalink
Post by aioritos
Al enviar la primera lectura del fichero me dice "Broken Pipe"
Parece cosa de que no has abierto correctamente la conexión de datos.
Post by aioritos
He comprobado que la longitud esta bien, pero si envío caracter a
caracter igualmente me dice Broken PIpe...
Idem.
Post by aioritos
No se que más hacer ya.. te importa que te mande el fichero a ver si
ves alguna solución?
Envíamelo al correo personal (quítale el "QUITARSPAM" :).

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-06 11:43:00 UTC
Permalink
Bueno ya está.

Espero que entre los dos lo saquemos...

Gracias.
Oscar Garcia
2005-07-06 11:52:05 UTC
Permalink
Post by aioritos
Bueno ya está.
Espero que entre los dos lo saquemos...
No me llega tu correo, por si las moscas envíamelo también a:

***@SPAMlinaresdigital.com

Que no se te olvide quitar las palabras en mayúsculas :)
Post by aioritos
Gracias.
De nada.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-07 07:48:42 UTC
Permalink
Hola, espero que ahora si te llegue.

Te lo he enviado desde dos correos distintos por si acaso.

Saludos.
Oscar Garcia
2005-07-07 07:53:44 UTC
Permalink
Post by aioritos
Hola, espero que ahora si te llegue.
Te lo he enviado desde dos correos distintos por si acaso.
Ahora sí.

Tengo que trabajar ahora y no podré ver el código hasta mi siguiente
"ventana" (o hueco libre). Luego te comentaré lo que vea extraño.

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-07 08:07:32 UTC
Permalink
Ok

Gracias
Oscar Garcia
2005-07-08 07:50:07 UTC
Permalink
Post by aioritos
ACONTINUACION ESTO (como basicamente es un copy paste, no se muy bien
explicar.Se supone que el resutado es la direccion IP separada por
comas, y lo que me lia bastante es los dos ultimos, los del puerto)
sprintf(port_name, "PORT %d,%d,%d,%d,%d,%d\r\n",
(host_id & 0x000000FF),
(host_id & 0x0000FF00) >> 8,
(host_id & 0x00FF0000) >> 16,
(host_id & 0xFF000000) >> 24,
(name.sin_port & 0xFF00) >> 8,
(name.sin_port & 0x00FF));
Tras mucho leer el código (y releerlo) finalmente al hacer un netstat
para observar los puertos que estaban a la escucha me dí cuenta de un
pequeño detalle en tu aplicación: ¡estaba escuchando en el puerto
equivocado!

¿Porqué?

Tu aplicación calcula el puerto de la siguiente manera:
random_port = (random_port + 7) % 500;
name.sin_port =htons(FTP_PORT_DATA + random_port);

Y posteriormente hace lo del sprintf:
sprintf(port_name, "PORT %d,%d,%d,%d,%d,%d\r\n",
(host_id & 0x000000FF),
(host_id & 0x0000FF00) >> 8,
(host_id & 0x00FF0000) >> 16,
(host_id & 0xFF000000) >> 24,
(name.sin_port & 0xFF00) >> 8,
(name.sin_port & 0x00FF));

¿Dónde está el error?

Pues que el autor de este código trabajaba en una máquina big endian
(como los power PC, motorolas en general, por ejemplo) y no en una
little endian como los procesadores Intel.

En su máquina htons no hace nada. No necesita transformar el puerto al
formato de red porque la máquina nativamente trabaja en formato de
red, los procesadores de Intel no.

Sin embargo en nuestras máquinas Intel o compatibles (procesadores
VIA, AMD, Cyrix, etc) se intercambia el byte más significativo por el
menos significativo.

¿Qué problema hay? Pues que el cálculo:
(name.sin_port & 0xFF00) >> 8,
(name.sin_port & 0x00FF));
Es independiente de la plataforma, y sin embargo hemos trabajado con
valores ya convertidos a formato de red.

¿Solución? Hay dos soluciones.

1.- Usar un unsigned short (llamado puerto por ejemplo) para almacenar
el puerto:

random_port = (random_port + 7) % 500;
puerto = FTP_PORT_DATA + random_port;
name.sin_port =htons(puerto);
name.sin_addr.s_addr = * ((int *) (host_data->h_addr_list[0]));
sprintf(port_name, "PORT %d,%d,%d,%d,%d,%d\r\n",
(host_id & 0x000000FF),
(host_id & 0x0000FF00) >> 8,
(host_id & 0x00FF0000) >> 16,
(host_id & 0xFF000000) >> 24,
(puerto & 0xFF00) >> 8,
(puerto & 0x00FF));

2.- Hacer el htons tras el sprintf:

random_port = (random_port + 7) % 500;
name.sin_port = FTP_PORT_DATA + random_port;
name.sin_addr.s_addr = * ((int *) (host_data->h_addr_list[0]));
sprintf(port_name, "PORT %d,%d,%d,%d,%d,%d\r\n",
(host_id & 0x000000FF),
(host_id & 0x0000FF00) >> 8,
(host_id & 0x00FF0000) >> 16,
(host_id & 0xFF000000) >> 24,
(puerto & 0xFF00) >> 8,
(puerto & 0x00FF));
name.sin_port = htons(name.sin_port);

Tras hacer esas modificaciones el código funciona perfectamente.

Un saludo.
P.D.: Yo personalmente prefiero usar PASV que PORT, me hubiera evitado
este error tan trivial.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-08 09:43:38 UTC
Permalink
Entonces para que me quede totalmente claro.
Lo que debo poner es esto:

random_port = (random_port + 7) % 500;
puerto = FTP_PORT_DATA + random_port;
name.sin_port =htons(puerto);

sprintf(port_name, "PORT %d,%d,%d,%d,%d,%d\r\n",
(host_id & 0x000000FF),
(host_id & 0x0000FF00) >> 8,
(host_id & 0x00FF0000) >> 16,
(host_id & 0xFF000000) >> 24,
(puerto & 0xFF00) >> 8,
(puerto & 0x00FF));

name.sin_port = htons(name.sin_port);
name.sin_addr.s_addr = * ((int *) (host_data->h_addr_list[0]));

No se si es por el servidor, o por que soy gafe, pero en mi ordenador
no me va.... se queda esperando ....
aioritos
2005-07-08 09:45:30 UTC
Permalink
Por cierto que gracias por aprovechar esa "ventana" mirando el código..
Oscar Garcia
2005-07-08 10:16:34 UTC
Permalink
Post by aioritos
random_port = (random_port + 7) % 500;
puerto = FTP_PORT_DATA + random_port;
name.sin_port =htons(puerto);
No se si es por el servidor, o por que soy gafe, pero en mi ordenador
no me va.... se queda esperando ....
Una pregunta quizá un poco tonta... ¿has declarado la variable
"puerto" como unsigned short?

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-08 10:23:04 UTC
Permalink
si ...... unsigned short int puerto;
Oscar Garcia
2005-07-08 10:38:37 UTC
Permalink
Post by aioritos
si ...... unsigned short int puerto;
Entonces especifica el fallo que te da, porque entonces no lo entiendo
(a mi ya me funciona tu aplicación).

¿Es un error de compilación? ¿En tiempo de ejecución?

Un saludo.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Oscar Garcia
2005-07-08 10:39:45 UTC
Permalink
Post by aioritos
si ...... unsigned short int puerto;
Acabo de leer que es que se queda esperando. Te paso el código que te
he modificado (siento haberte modificado casi todo tu código, era
necesario para añadir información de "debug").

Cuando lo compiles en tu casa me avisas si te funciona o no.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-08 11:44:26 UTC
Permalink
Hola!

Que maravilla!

por fin puedo hacer transferencia de archivos!

pero sólo con el "put"

Al hacer el "get" no me copia el contenido, pero en la información de
debug que pones, sale como si la transferencia se hubiera realizado
correctamente.
Esta es la traza:

ftp> get
Parsing String.
Cut off the first token. "get"
(remote-file) get.txt
(local-file) ee.txt
local-> ee.txt, remote-> get.txt
Debug: 60974, 3556812992d, PORT 192,168,0,212,46,238
Debug: RETR get.txt
Error: 0 (BUFFER: 4076)
(3)>> PORT 192,168,0,212,46,238 (27 bytes)
<<(3) 226 Transfer complete. (24 bytes)
226 Transfer complete.
(3)>> TYPE I (8 bytes)
<<(3) 200 PORT command successful (29 bytes)
200 PORT command successful
(3)>> MODE S (8 bytes)
<<(3) 200 Type set to I (19 bytes)
200 Type set to I
(3)>> RETR get.txt (14 bytes)
Entrando en el accept
Saliendo del accept
<<(6) HOLA QUE TAL ESTAS (19 bytes)
<<(3) 200 Mode set to S.
150 Opening BINARY mode data connection for get.txt (19 bytes)
(84 bytes)
200 Mode set to S.
150 Opening BINARY mode data connection for get.txt (19 bytes)


Muchas gracias, de veras; cuando tengas algún problema que mis
conocimientos abarquen a solucionar... estaré encantado de ayudarte.
Oscar Garcia
2005-07-08 14:06:25 UTC
Permalink
Post by aioritos
Muchas gracias, de veras; cuando tengas algún problema que mis
conocimientos abarquen a solucionar... estaré encantado de ayudarte.
Me conformo con que te mantengas por el grupo de noticias y aportes tu
ayuda a quien lo necesite :)

Un saludo y de nada (ahora después le echaré un vistazo al get).
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Oscar Garcia
2005-07-08 14:43:32 UTC
Permalink
Post by aioritos
Al hacer el "get" no me copia el contenido, pero en la información de
debug que pones, sale como si la transferencia se hubiera realizado
correctamente.
Tras enviar el comando STOR o RETR debes leer la respuesta:
150 Opening BINARY mode data connection for archivo_tal

Si no lo haces habrás visto que se va acumulando esa respuesta en
sucesivos comandos quedándose desincronizadas las órdenes que envías
con sus respuestas:

send_s(control_socket_id, command, strlen(command), 0);

// Añadir lo siguiente (quitar los comentarios que tenían)
errorlevel = get_response(control_socket_id);

switch (errorlevel) {
case 550 : destroy_connection(data_id);
return -1;
break;
}

Y para que el archivo se escriba correctamente hay que cambiar:

errorlevel = recv_s(data_id, listing, sizeof(char) * BUFFER, 0);
while (errorlevel != 0) {
fwrite(listing, errorlevel, BUFFER, local_file);
errorlevel = recv_s(data_id, listing, sizeof(char) * BUFFER, 0);
}

por

while ((errorlevel = recv_s(data_id, listing, sizeof(listing), 0))
!= 0) {
fwrite(listing, sizeof(char), errorlevel, local_file);
}

Por optimizar el código y hacer las cosas bien (si no te encontrarás
con un archivo vacío).

Tras darme cuenta que se escribía mucha basura en el archivo subido
mediante put me he dado cuenta que también la función de transferencia
de archivos está mal escrita:

errorlevel = fread(listing, sizeof(char), BUFFER, local_file);
while (errorlevel != 0) {
send_s(data_id, listing,BUFFER, 0);
errorlevel = fread(listing, sizeof(char), BUFFER, local_file);
}

Debes cambiarlo por:

while (( errorlevel = fread(listing, sizeof(char), BUFFER,
local_file)) != 0) {
send_s(data_id, listing, errorlevel, 0);
}

Si no los archivos se escribirían en el disco duro como múltiplos de
datos de BUFFER bytes.

Otro saludo y espero que sea ya el definitivo de este hilo :)

¡Felices vacaciones a todo el mundo!
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-11 07:49:16 UTC
Permalink
Bueno, gracias por todo, parece que este es el fin del tema....

En cuanto a la parte de "STOR", ya me di cuenta y lo arreglé leyendo
caracter a caracter... aunque de esta forma lo hace de golpe.

Hasta otra y gracias de nuevo!!

Loading...