Thread FTP Socket flush
(3 answers)
Opened by rosti at 2025-07-30 07:21
Wer das mal testen möchte
Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 package MyFTP; # Nur zum Senden von Dateien use strict; use warnings; use IO::Socket; use constant CRLF => "\r\n"; use File::Basename; use IO::File; $| = 1; sub new{ my $class = shift; my %cf = ( host => '', # FTP Host user => '', # FTP User pass => '', # FTP Passwort port => 21, # FTP Port root => '', # FTP Root absoluter Pfad auf dem Server @_); return eval{ my $self = bless{ cfg => \%cf }, $class; my $cmd = IO::Socket::INET->new( PeerHost => $cf{host}, PeerPort => $cf{port}, Timeout => 3 ) or die "$!\n"; $self->{cmd} = $cmd; $self->_read_status_line(); print $self->response; $self->_login(); $self; } } # z.B. 250 CWD command successful sub response{ my $self = shift; $self->{response}."\n"; } # Socket für die Daten im Passiv-Mode sub _passiv{ my $self = shift; $self->_command("PASV"); print $self->response; # 227 Entering Passive Mode (185,146,238,137,223,229). # Port für das Datensocket $self->{statusline} =~ /(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/; my $dataport = $5*256 + $6; $self->{DATA} = IO::Socket::INET->new( PeerHost => $self->{cfg}{host}, PeerPort => $dataport, ) or die $^E; } # https://www.elektronik-kompendium.de/sites/net/0902241.htm sub _command{ my $self = shift; my $command = shift; $self->{cmd}->print($command.CRLF); $self->_read_status_line(); } sub _login{ my $self = shift; my $user = $self->{cfg}{user}; my $pass = $self->{cfg}{pass}; $self->_command("USER $user"); print $self->response; $self->_command("PASS $pass"); print $self->response; die "Anmeldung fehlgeschlagen\n" if $self->{status} != 230; } # Lese Socket Steuerkanal sub _read_status_line{ my $self = shift; my $str = $self->{cmd}->getline; $str = unpack "A*", $str; $self->{response} = $str; ($self->{status}, $self->{statusline}) = split /\s+/, $str, 2; return $str; } # Change Dir, Übergeben wird der absolute Pfad, Root-Dir wird abgeschnitten sub chdir{ my $self = shift; my $dir = shift; $dir =~ s/$self->{cfg}{root}//; $self->_command("CWD $dir"); print $self->response; die "Ungültiges Verzeichnis '$dir'\n" unless $self->{status} == 250; $self->_command("PWD"); print $self->response; } # Datensocket herstellen, Datei senden, Dateiname mit vollst. Pfad sub putfile{ my $self = shift; $self->_passiv; my $fullname = shift; my($name,$path,$suffix) = fileparse($fullname); my $fh = IO::File->new(); $fh->open($fullname, O_BINARY|O_RDONLY) or die $^E; $self->_command("STOR $name"); print $self->response; my $data = $self->{DATA}; my $len = 0; while( my $x = read($fh, my $buffer, 2048) ){ print "#"; $data->print($buffer); $len += $x; } print "\n"; $data->close; $self->_read_status_line; # 226 Transfer complete if( $self->{status} != 226 ){ die "Put '$name' nicht erfolgreich\n"; } else{ print $self->response; } } # FTP-Sitzung beenden sub quit{ my $self = shift; $self->_command("QUIT"); print $self->response; } 1; __END__ my $ftp = MyFTP->new( %ced ) or die $@; $ftp->chdir("/var/www/vhosts/rolfrost.de/files/tmp"); $ftp->putfile("/var/www/vhosts/rolfrost.de/files/dbf.bin"); $ftp->putfile("/var/www/vhosts/rolfrost.de/files/testfile.txt"); $ftp->quit; Die Ausgabe zeigt jede Antwortzeile gem. Protokoll und je 4 kB wird ein Hash-Zeichen ausgegeben. Ideal für FTP über die rechte Maustaste Senden an im Kontextmenu! . Last edited: 2025-07-31 18:07:43 +0200 (CEST) |