Newsgroup: it.comp.lang.perl
Titolo: ftp in perl

Ciao a tutti  sto cercando di fare una transazione ftp usando
 i socket con  perl ma non ce' verso mi da sempre degli errori.
 Se uso Net::FTP riesco a scaricare il file da remoto ma con i socket
 niente da fare vi mando il codice se qualcuno me lo potesse correggere
 o illuminarmi dove erro gli e ne sare molto grato
#!/usr/bin/perl       -w
      use Socket;
      $command[0]="USER ";
      $command[1]="PASS ";
      $command[2]="RETR ";
      $command[3]="PORT ";
      $host=$ARGV[0];
      $user=$ARGV[1];
      $pass=$ARGV[2];
      $patch=$ARGV[3];
      $bufs="$command[0]"."$user"."\n";
      $len=length($bufs);
      socket($mysockh,PF_INET,SOCK_STREAM,getprotobyname('tcp'))||die $!;  #
      my $sin=sockaddr_in(1045,inet_aton($host));                           
                     #   Mi connetto al server
      bind($mysockh,$sin)|| $!;                                             
                                    #   specificando pel la porta del client
      my $dest=sockaddr_in(21,inet_aton($host));                            
                      #   1045
      connect($mysockh,$dest)||die $! ;                                     
                              #
      recv($mysockh,$bufr,100,0)|| die $!;                                  
                              #  Ricevo i dati dal server
      print "$bufr\n";
      send($mysockh,$bufs,$len,0)|| die $!;                                 
                             # Spedisco   user
      recv($mysockh,$bufr,100,0)|| die  $!;                                 
                               # ricevo risposta dal server
      print "$bufr";
      $bufs="$command[1]"."$pass"."\n";                                     
                             #Spedisco pass
      $len=length($bufs);                                                   
                                       # ricevo come sopra
      send($mysockh,$bufs,$len,0)|| die $!;
      recv($mysockh,$bufr,100,0)|| die $!;
      print "$bufr\n";
 
                                                   #Spedisco port al serve 
per
      $bufs="$command[3]"."127,0,0,1,4,22\n";                               
                           #specificare la porta
      $len=length($bufs);                                                   
                                        #(2*256)+22=1046
      send($mysockh,$bufs,$len,0);                                          
                                 #spedisco e ricevo la risposta
       recv($mysockh,$bufr,100,0);                                          
                                   #da server
      print "$bufr\n";
      $bufs="$command[2]"."$patch"."\n";                                    
                               #spedisco retr percorso file
      $len=length($bufs);                                                   
                                         #da prelevare e ricevo come sopra
      send($mysockh,$bufs,$len,0)|| die $!;
      recv($mysockh,$bufr,100,0)|| die $!;
      print "$bufr\n";
      close($mysockh);                                                      
                                       # chiudo il l'handle 
       print "$?\n";
l'output e' il seguente 
[root@localhost ftp]# ./
clientftp.pl
  127.0.0.1 ciclope  1occhioceco  prova
220 ProFTPD 1.2.2rc1 Server (ProFTPD Default Installation) 
[localhost.localdomain]
331 Password required for ciclope.
230 User ciclope logged in.
200 PORT command successful.
425 Can't build data connection: Connection refused
0
[root@localhost ftp]# 
ciao.

  o illuminarmi dove erro gli e ne sare molto grato
Vedo *una* sola chiamata a socket() e *una* sola chiamata a bind(). Questo
è sufficiente per intuire che il tuo programma si aspetta di ricevere il
file sull'unico canale aperto (che è quello di controllo). Ti suggerirei
di leggerti le specifiche del protocollo FTP (RFC 959). Secondo me, però,
dovresti usare Net::FTP e dedicare il tuo tempo a studiare cose più
interessanti. Ad ogni modo, in modalità standard (non passive, cioè), le
operazioni che deve fare il client per trasferire o ricevere un file
grosso modo sono:
   - bind + listen su una porta alta
   - invio comando PORT appropriato (v. RFC)
   - invio comando RETR o STOR 
   - accept 
   - ricezione o trasmissione
Max

 
Ti ringrazio molto di avermi risposto adesso vediamo
se ho capito giusto
piu' o meno dovrei scrivere uno script che faccia questo
1) Aprire un canale di controllo.
2) Comunicare al server tramite il canale di controllo la porta alta su cui 
     mi mettero in ascolto per ricevere i dati.
3) Mettersi in ascolto sulla porta alta.
4) Inviare retr o stor sul canale di controllo.
5) Ricevere o Spedire i dati sul canale dati.
Ora purtroppo dato che sono un principiante nel perl ed autodidatta ho 
delle difficolta
a scrivere questo script che ha due socket aperti contemporaneamente ,Per 
esempio
quando mi metto in ascolto usando listen e accept lo script si congela 
aspettando la
connessione dal server che a sua volta si aspetta retr sul canale di 
controllo ma che non
arrivera' mai. Ora avro' scritto sicuramente delle bestialita' ma e tutto 
quello che sono riuscito
a capire studiandoci da solo tenendo conto che l'inglese non e' il mio 
massimo.  l'RFC
959 lo scaricata dalla rete in spagnolo e in inglese ma e' un testo troppo 
complicato da leggere
in una lingua straniera .Invece mi son trovato bene con il testo in ita di 
Dario de judicibus
"Il protocollo per il trasferimento dati",mentre invece zero con la ricerca 
di  codice esempio.
Se tu potessi darmi qualche consiglio su come scrivere lo script cosi' 
potrei andare avanti.
Ciao ti ringrazio.

 potrei andare avanti.
Alcuni consigli: 
  - leggiti bene un testo che illustri le specifiche del
    protocollo FTP
  - studiati il codice di Net/FTP.pm
  - non usare le API BSD tradizionali, ma usa IO::Socket
Max

Grazie Max ce lo fatta.
Opening ASCII mode connection for /prova (6243 bytes).
Transfer complete. 
Grazie ancora.
Spero di cosrtuire un bel client ciao.

 Max
Saluti,
Lord Knight
--
with all due respect

 forse ?
Certo. Io mi riferivo esclusivamente al protocollo FTP, non alla
programmzione network in generale. Mi sembrava che l'OP volesse
sostanzialmente riuscire a trasferire un file in FTP, cosa che è piuttosto
semplice da ottenere, ma poco interessante da implementare. Tutto qui.
Max