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

ITobiI
 2015-10-18 13:07
#182656 #182656
User since
2015-09-10
70 Artikel
BenutzerIn
[default_avatar]
Ok, alles klar wenn es so nicht geht das ist es doch in Ordnung, wollte nur was ausprobieren ;) Dann muss ich es wohl doch so machen:
Code: (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
#!/usr/bin/perl -w
#TCP-Server
#Hartych, Tobias EIT 4056051
#Dreißig, Tobias EIT 4056501

use strict; #strict macht debugging einfacher
use IO::Socket::INET; #nutze Modul IO::Socket::INET um einen neuen Socket zu erschaffen

#Variablen deklarieren
my ($socket,$connection,$end);
my($peeradr,$peerport);
my ($Bestaetigung_daten,$checksum_Client,$checksum_Server,$fh,$sort_daten,$Bestaetigung_checksum);
my ($unzip_daten,$zip_daten,$status,$UnzipError,$laenge_Client,$laenge_Server,$SIG);

my $NPort = $ARGV [1] || "9999"; #zweiter Paramenter wird in $NPort eingespeichert

my $ipAddress = $ARGV [0] || "127.0.0.1"; #erster Paramenter wird in $ipAddress eingespeichert

$socket = new IO::Socket::INET
(
LocalHost => $ipAddress, #LocalHost von $socket ist eingegebener Paramenter $ipAddress
LocalPort => $NPort, #LocalPort von $socket ist eingegebener Paramenter $NPort
Proto => 'tcp', #Transportprotokoll: TCP
Listen => 5, #maximale Anzahl von Client's ist 5
Reuse => 1

);
die "Fehler beim erstellen des Socket's: $!\n" unless $socket;

print "Warte auf Verbindung mit Client ..\n";


#Warte auf Verbindung zum Client / Akzeptiere eingehende Client Verbindung
$connection = $socket->accept();
$peeradr = $connection->peerhost();
$peerport = $connection->peerport();

print "TCP Server bereit und wartet auf eine Verbingung mit Port $NPort\n";

#Hauptschleife
while(1)
{
#Empfange Länge der Daten
$connection->recv($laenge_Client,4);

#Empfange und Prüfe Empfang Prüfsumme
do
{
#Bestätige nicht erfolgreiches Senden
$Bestaetigung_checksum = 0;
$connection->send($Bestaetigung_checksum);

#Empfange Prüfsumme von Client
$connection->recv($checksum_Client,8);
}
while (length($checksum_Client) < 4);

#Bestätige erfolgreiches Senden
$Bestaetigung_checksum = 1;
$connection->send($Bestaetigung_checksum);

print "1\n";


#Empfange und überprüfe Empfang Daten
do
{
#Bestätige nicht erfolgreiches Senden
$Bestaetigung_daten = 0;
$connection->send($Bestaetigung_daten);

print "11\n";
#Empfange Daten
do
{
#Empfang der Daten mit Timeout
eval
{
local $SIG{ALRM} =sub {die};
alarm(1);

$connection->recv($zip_daten,1024);

alarm(0);
};

#Bilde Länge der empfangenen Daten
$laenge_Server = length($zip_daten);
}
while($laenge_Client != $laenge_Server);

#Bilde Prüfsumme nach Empfang der Daten
#$checksum_Server = unpack ("%16C*", $unzip_daten);
use Digest::MD5 qw(md5_hex);
$checksum_Server = md5_hex($zip_daten);

print("Prüfsumme: $checksum_Server\n");
print "12\n";
}
while ($checksum_Client != $checksum_Server);

print "2\n";

#Bestätige erfolgreiches Senden
$Bestaetigung_daten = 1;
$connection->send($Bestaetigung_daten);

print "3\n";

#Entpacke
$unzip_daten = '';
use IO::Uncompress::Unzip qw(unzip $UnzipError);
$status = unzip \$zip_daten => \$unzip_daten or die "unzip schlug fehl: $UnzipError\n";

#Gib Datei aus
print "Daten:\n $unzip_daten";

#lösche Inhalt
$zip_daten = ();
$unzip_daten = ();

#Abfrage ob Programm beenden
print "\nWenn Programm durchgeführt werden soll dann bitte j eingeben, ansonsten beliebiges anderes Zeichen eingeben\n";
$end = <STDIN>;
chop($end);

if($end eq 'j')
{
#Programm beenden
close($socket);
exit();
}
}

#Schließe Socket -> schliesse Verbindung zum Client
$socket -> close();

Code: (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
#!/usr/bin/perl -w

#TCP-Client
#Hartych, Tobias EIT 4056051
#Dreißig, Tobias EIT 4056501

use Time::HiRes qw(gettimeofday);
use strict; #strict macht debugging einfacher
use IO::Socket::INET; #nutze Modul IO::Socket::INET um einen neuen Socket zu erschaffen

my ($socket,$peeradr,$peerport,$end,$start_sec,$start_usec,$end_sec,$end_usec,$timeDelta,$checksum_Client,$Bestaetigung_checksum);
my ($daten,$Bestaetigung_daten,$zip_daten,$status,$ZipError,$laenge_Client,$FH);

#bekomme server-ip und server-port von Kommandozeilenparamter
$peeradr = $ARGV [0] || "127.0.0.1"; #erster Paramenter wird in $PeerAdress eingespeichert

$peerport = $ARGV [1] || "9999"; #zweiter Paramenter wird in $PeerPort eingespeichert

$socket = new IO::Socket::INET
(
PeerHost => $peeradr, #PeerAddr von $socket ist eingegebener Paramenter $PeerAdress
PeerPort => $peerport, #PeerPort von $socket ist eingegebener Paramenter $PeerPort
Proto => 'tcp', #Transportprotokoll: TCP
);
die "Fehler bei erstellen des Socket's: $!\n" unless $socket;

print "\nVerbindung mit Server erfolgreich!\n";
print "Mit $peeradr verbunden !\n";

#Hauptschleife
while(1)
{
#Datei in String einlesen
open($FH, "<", "/root/Documents/Socket-Programmierung_2/Datei/Test") or die $!;
binmode $FH;
$daten = <$FH>;

#packen
$zip_daten = '';
use IO::Compress::Zip qw(zip $ZipError);
$status = zip \$daten => \$zip_daten or die "zip schlug fehl!: $ZipError\n";

#Länge des Strings ermitteln
$laenge_Client = length($zip_daten);

#Sende Länge der Daten zu Server
$socket->send($laenge_Client);

#Prüfsumme ermitteln
#$checksum_Client = unpack ("%16C*", $daten);
use Digest::MD5 qw(md5_hex);
$checksum_Client = md5_hex($zip_daten);


$Bestaetigung_checksum = 0;

while($Bestaetigung_checksum == 0)
{
#Bestaetigung erhalten
$socket->recv($Bestaetigung_checksum,2);

if($Bestaetigung_checksum == 0)
{
#Prüfsumme an Server senden
$socket->send($checksum_Client);
print("Prüfsumme: $checksum_Client\n");
}
}

$Bestaetigung_daten = 0;

print "3\n";

#Startzeit setzen
($start_sec, $start_usec) = gettimeofday();

while($Bestaetigung_daten == 0)
{
print "31\n";
#Bestaetigung erhalten
$socket->recv($Bestaetigung_daten,2);
print "32\n";
if($Bestaetigung_daten == 0)
{
print "33\n";
#sende Datenpakete zu Server
$socket->send($zip_daten);
print "34\n";
}
}

#Endzeit setzen
($end_sec, $end_usec) = gettimeofday();

print "4\n";

#Sendezeit ermitteln
$timeDelta = ($end_usec - $start_usec)/1000 + ($end_sec - $start_sec)*1000;
print "Die Sendezeit betraegt: $timeDelta ms\n";

#lösche Inhalt
$daten = ();
$zip_daten = ();

#Abfrage ob Programm beenden
print "Wenn Programm durchgeführt werden soll dann bitte j eingeben, ansonsten beliebiges anderes Zeichen eingeben\n";
$end = <STDIN>;
chop($end);

if($end eq 'j')
{
#Programm beenden
close($socket);
exit();
}
}

#Schließe Socket
$socket -> close();

Aber 2 Fragen hät ich noch:
1. Kann ich das mit dem Timeout so machen wenn ein Datenpaket verloren geht?
2. Muss ich vor dem Senden Daten die Daten in einen Buffer laden, falls ein Datenpaket verloren geht, oder bleiben die ursprünglichen Daten solange im Client ,,gespeichert" bis ich etwas anderes sage?
Was man vielleicht noch machen könnte:
- Überprüfen welche Datenpakete fehlen
- Dem Client mitteilen das er diese Datenpakete erneut senden soll
- erneute Überprüfung
- Datenpakete wieder in richtige Reihenfolge bringen
Aber um das zu realisieren kenne ich den Syntax leider nicht :(
Last edited: 2015-10-18 13:14:09 +0200 (CEST)

View full thread Fehlerfreie Übertragung von Daten (2)