Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TRANSFERENCIA FICHEROS EN CLIENTE FTP

4 views
Skip to first unread message

aioritos

unread,
Jun 23, 2005, 7:51:13 AM6/23/05
to
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

unread,
Jun 23, 2005, 10:16:37 AM6/23/05
to
El 23 Jun 2005 04:51:13 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>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).

>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...

>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.

>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.

>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.

>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).

>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.

>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 creo que sea problema del sizeof.

>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ú.

>GRACIAS!!

De nada.

--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/

aioritos

unread,
Jun 24, 2005, 4:05:07 AM6/24/05
to
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

unread,
Jun 24, 2005, 5:14:11 AM6/24/05
to
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

unread,
Jun 24, 2005, 5:27:13 AM6/24/05
to
El 24 Jun 2005 02:14:11 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>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".

>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.

aioritos

unread,
Jun 24, 2005, 5:57:50 AM6/24/05
to
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

unread,
Jun 30, 2005, 4:11:15 AM6/30/05
to
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

unread,
Jul 1, 2005, 5:08:07 AM7/1/05
to
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

unread,
Jul 1, 2005, 5:16:45 AM7/1/05
to
El 1 Jul 2005 02:08:07 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>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.

¿Tras enviar el comando PASV le envias el GET o el PUT?

aioritos

unread,
Jul 1, 2005, 5:40:41 AM7/1/05
to
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

unread,
Jul 1, 2005, 5:57:01 AM7/1/05
to
El 1 Jul 2005 02:40:41 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>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)

¿Y cuando envias el archivo por el canal de datos?

>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.

>Gracias.

De nada.

aioritos

unread,
Jul 1, 2005, 6:07:55 AM7/1/05
to
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

unread,
Jul 1, 2005, 11:20:32 AM7/1/05
to
El 1 Jul 2005 03:07:55 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>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.

>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

aioritos

unread,
Jul 5, 2005, 7:02:01 AM7/5/05
to
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

unread,
Jul 5, 2005, 8:05:30 AM7/5/05
to
El 23 Jun 2005 04:51:13 -0700, "aioritos" <ircr...@hotmail.com>
escribió:
>Al enviar la primera lectura del fichero me dice "Broken Pipe"

Parece cosa de que no has abierto correctamente la conexión de datos.

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

Idem.

>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.

aioritos

unread,
Jul 6, 2005, 7:43:00 AM7/6/05
to
Bueno ya está.

Espero que entre los dos lo saquemos...

Gracias.

Oscar Garcia

unread,
Jul 6, 2005, 7:52:05 AM7/6/05
to
El 6 Jul 2005 04:43:00 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>Bueno ya está.
>Espero que entre los dos lo saquemos...

No me llega tu correo, por si las moscas envíamelo también a:

oscar...@SPAMlinaresdigital.com

Que no se te olvide quitar las palabras en mayúsculas :)

>Gracias.

De nada.

aioritos

unread,
Jul 7, 2005, 3:48:42 AM7/7/05
to
Hola, espero que ahora si te llegue.

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

Saludos.

Oscar Garcia

unread,
Jul 7, 2005, 3:53:44 AM7/7/05
to
El 7 Jul 2005 00:48:42 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>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.

aioritos

unread,
Jul 7, 2005, 4:07:32 AM7/7/05
to
Ok

Gracias

Oscar Garcia

unread,
Jul 8, 2005, 3:50:07 AM7/8/05
to
El 23 Jun 2005 04:51:13 -0700, "aioritos" <ircr...@hotmail.com>
escribió:
>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.

aioritos

unread,
Jul 8, 2005, 5:43:38 AM7/8/05
to
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

unread,
Jul 8, 2005, 5:45:30 AM7/8/05
to
Por cierto que gracias por aprovechar esa "ventana" mirando el código..

Oscar Garcia

unread,
Jul 8, 2005, 6:16:34 AM7/8/05
to
El 8 Jul 2005 02:43:38 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

> 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.

aioritos

unread,
Jul 8, 2005, 6:23:04 AM7/8/05
to
si ...... unsigned short int puerto;

Oscar Garcia

unread,
Jul 8, 2005, 6:38:37 AM7/8/05
to
El 8 Jul 2005 03:23:04 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>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?

Oscar Garcia

unread,
Jul 8, 2005, 6:39:45 AM7/8/05
to
El 8 Jul 2005 03:23:04 -0700, "aioritos" <ircr...@hotmail.com>
escribió:
>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.

aioritos

unread,
Jul 8, 2005, 7:44:26 AM7/8/05
to
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

unread,
Jul 8, 2005, 10:06:25 AM7/8/05
to
El 8 Jul 2005 04:44:26 -0700, "aioritos" <ircr...@hotmail.com>
escribió:

>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).

Oscar Garcia

unread,
Jul 8, 2005, 10:43:32 AM7/8/05
to
El 8 Jul 2005 04:44:26 -0700, "aioritos" <ircr...@hotmail.com>
escribió:
>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!

aioritos

unread,
Jul 11, 2005, 3:49:16 AM7/11/05
to
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!!

0 new messages