Thread Fehlerfreie Übertragung von Daten (2) (9 answers)
Opened by ITobiI at 2015-10-15 19:46

Gast janus
 2015-10-18 07:40
#182652 #182652
Zum Verständnis: Socket ist InOut, da gibt es keine Array's sondern nur noch nackte Bytes. Untenstehend mal ein bischen Code zum Einstieg in die Thematik Übertragen von Dateien. Gecheckt wird in meinem Fall die Dategröße und wenn Du Lust hast, erweitere das so, dass eine Checksumme MD5 oder SHA gebildet wird.

Zum Übertragen habe ich mich im Beispiel für HTTP entschieden und weil es mehrere Dateien sind, setzen wir Version HTTP/1.1 und Request-Header Connection: Keep-Alive. So hält der Webserver das Socket solange offen, bis alle Dateien hochgeladen sind, d.h., für jede lokale Datei wird ein Request gefeuert. Dann wird ein Request nachgeschoben mit Header Connection: Close und schließlich wird aus der gesamten Response mit einer RegEx das Ergebnis geparst.

Hier das serverseitige CGI-Script:
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
#!/usr/bin/perl

# Dateien empfangen und serverseitig speichern

use strict;
use warnings;
use IO::File;
use File::Copy;

chdir "/tmp"; 
# Request-Header x-upload: filename
if( my $filename = $ENV{HTTP_X_UPLOAD} ){
    my $fh = IO::File->new;
    $fh->open("/tmp/$filename", O_CREAT|O_BINARY|O_TRUNC|O_RDWR) or die $!;
    copy *STDIN, $fh;
    my $size = -s $fh;
    $fh->close;
    print 
        "Content-Length: 0\n",
        "Content-Type: text/plain\n\n",
        "$filename==$size\n\n";
    # Letzteres wird aus der Response geparst zu einem Hash
}
else{
    print
        "Content-Length: 0\n",
        "Content-Type: text/plain\n\n",
        "Done";
}


und der lokale HTTP-Client
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
#!/usr/bin/perl

use strict;
use warnings;
use IO::Socket;
use IO::File;
use Data::Dumper;

binmode STDOUT;

my $sock = IO::Socket::INET->new('localhost:80') or die $!;

# Lade ein paar Textdateien hoch
my $check = {}; # hashref zum Gegenchecken
my @files = <*.txt>;
foreach my $filename(@files){
    my $content = do{
        my $fh = IO::File->new;
        $fh->open($filename, O_BINARY|O_RDONLY) or die $!;
        read($fh, my $buffer, -s $fh);
        $check->{$filename} = -s $fh;
        $fh->close;
        $buffer;
    };

# Request-Header x-upload: filename
print $sock 
<<"EOT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~EOT";
PUT /cgi-bin/put.cgi HTTP/1.1
Host: localhost
Connection: Keep-Alive
Content-Length: @{[length($content)]}
x-upload: $filename

$content
EOT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~EOT
}


# Ergebnis abfragen
# Request
print $sock 
<<"EOT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~EOT";
GET /cgi-bin/put.cgi HTTP/1.1
Host: localhost
Connection: Close

EOT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~EOT

# Response
my $response = '';
$response .= $_ while <$sock>;

# Ausgabe Hash: Dateiname => Dateigröße
my $h = { $response =~ /(.*)==(\d+)/g };
print Dumper $response, $h, $check;

Last edited: 2015-10-18 10:49:29 +0200 (CEST)

View full thread Fehlerfreie Übertragung von Daten (2)