Thread FTP Socket flush (3 answers)
Opened by rosti at 2025-07-30 07:21

rosti
 2025-07-30 10:48
#197175 #197175
User since
2011-03-19
3656 Artikel
BenutzerIn
[Homepage]
user image
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)
http://blog.rolfrost.de/

The art of steam.

View full thread FTP Socket flush