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

ITobiI
 2015-10-20 18:04
#182674 #182674
User since
2015-09-10
70 Artikel
BenutzerIn
[default_avatar]
Hab den Fehler gefunden und habe meine ursprüngliche Version noch einmal überarbeitet. Hoffe es funktioniert jetzt so wie es soll:
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/usr/bin/perl -w

#UDP-Server

use warnings;
use IO::Select;
use strict 'vars'; #strict macht debugging einfacher
use IO::Socket::INET; #nutze Modul IO::Socket::INET um einen neuen Socket zu erschaffen
use POSIX;

#Variablen deklarieren
my ($socket,$end,$peer_address,$peer_port);
my ($Bestaetigung_checksum_daten,$checksum_Client,$checksum_Server,$fh,$sort_daten,$Bestaetigung_checksum,$Bestaetigung_laenge_daten,$i,$Anzahl_Pakete,$data,$server_socket);
my ($unzip_daten,$zip_daten,$status,$UnzipError,$laenge_Client,$laenge_Server);
my $maxTimeout = 1;

my @daten;

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

my $ipAddress = $ARGV [1] || "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 => 'udp' #Transportprotokoll: UDP
);
die "Fehler beim erstellen des Socket's: $!\n" unless $socket;

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

$server_socket = IO::Select->new($socket);


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

#Hauptschleife
while(1)
{
#Empfange Länge der Daten
$laenge_Client = '';
$socket->recv($laenge_Client,1024);
#definiere ip
$peer_address = $socket->peerhost();
#definiere port
$peer_port = $socket->peerport();
print "1\n";

#Ermittle Anzahl der Datenpakete
$Anzahl_Pakete = ($laenge_Client)/1024;

#Auf nächste Ganzzahl aufrunden
$Anzahl_Pakete = ceil($Anzahl_Pakete);

#Empfange und Prüfe Empfang Prüfsumme
do
{
print "21\n";
#Bestätige nicht erfolgreiches Senden
$Bestaetigung_checksum = 0;
$socket->send($Bestaetigung_checksum) or warn $!;

print "22\n";

#Empfange Prüfsumme von Client
if($server_socket->can_read($maxTimeout))
{
print "23\n";
$checksum_Client = '';
$socket->recv($checksum_Client,1024) or warn $!;
}

print "Prüfsumme: $checksum_Client\n";
print "24\n";
}
while (length($checksum_Client) == 0);

print "3\n";

#Bestätige erfolgreiches Senden
$Bestaetigung_checksum = 1;
$socket->send($Bestaetigung_checksum) or warn $!;

print "4\n";

#Empfange und überprüfe Empfang Daten
do
{
#Teile Client mit das Prüfsumme nicht übereinstimmt
print "5\n";
$Bestaetigung_checksum_daten = 0;
$socket->send($Bestaetigung_checksum_daten) or warn $!;

for($i=0; $i<$Anzahl_Pakete; $i++)
{
print "51\n";

$data = '';

#Empfange Daten
do
{
$Bestaetigung_laenge_daten = 0;

print "52\n";

#Bestaetige Daten keinen Inhalt enthält
$socket->send($Bestaetigung_laenge_daten) or warn $!;

#Empfang der Daten mit Timeout
if($server_socket->can_read($maxTimeout))
{
$socket->recv($data,1024) or warn $!;
}

print "54\n";

#Lege empfangene Daten in Array ab
$daten[$i] = $data;

#Bilde Länge der empfangenen Daten
$laenge_Server = length($data) or warn $!;
}
while($laenge_Server == 0);

print "55\n";

$Bestaetigung_laenge_daten = 1;

#Bestaetige Daten einen Inhalt enthält
$socket->send($Bestaetigung_laenge_daten);

$data = ();

}

print "56\n";

$zip_daten = join("",@daten) or warn $!;

#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 ne $checksum_Server);

print "6\n";

#Bestätige erfolgreiches Senden der Daten
$Bestaetigung_checksum_daten = 1;
$socket->send($Bestaetigung_checksum_daten) or warn $!;

print "7\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 = ();
$data = ();

#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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/bin/perl -w

#UDP-Client

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

my ($socket,$peeradr,$peerport,$end,$start_sec,$start_usec,$end_sec,$end_usec,$timeDelta,$checksum_Client,$Bestaetigung_checksum,$Bestaetigung_laenge_daten,$i,$Anzahl_Pakete,$data,$Trenn_Anfang,$Trenn_Ende,$client_socket);
my ($daten,$Bestaetigung_checksum_daten,$zip_daten,$status,$ZipError,$laenge_Client,$FH);
my $maxTimeout = 1;

#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 => 'udp' #Transportprotokoll: UDP
);
die "Fehler bei erstellen des Socket's: $!\n" unless $socket;

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

$client_socket = IO::Select->new($socket);

#Hauptschleife
while(1)
{
$Bestaetigung_checksum = 0;
$Bestaetigung_checksum_daten = 0;
$Bestaetigung_laenge_daten = 0;

#Datei in String einlesen
open($FH, "<", "/root/Documents/Socket-Programmierung_2/Datei/test.txt") 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) or warn $!;

#Ermittle Anzahl der Datenpakete
$Anzahl_Pakete = ($laenge_Client)/1024;

#Auf nächste Ganzzahl aufrunden
$Anzahl_Pakete = ceil($Anzahl_Pakete);

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

my $abc = length($Bestaetigung_checksum);
print "Länge Prüfsumme: $abc";

print "1\n";

while($Bestaetigung_checksum == 0)
{
print "21\n";

#Bestaetigung erhalten ob Prüfsumme erfolgreich gesendet wurde
do
{
if($client_socket->can_read($maxTimeout))
{
$socket->recv($Bestaetigung_checksum,16) or warn $!;
}
}
while(length($Bestaetigung_checksum) == 0);

print "Bestaetigung_checksum: $Bestaetigung_checksum\n";

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

print "3\n";

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

#Festlegung der Punkte an denen der String getrennt wird
$Trenn_Ende = 1024;
$Trenn_Anfang = 0;


while($Bestaetigung_checksum_daten == 0)
{
#Bestaetigung erhalten ob Prüfsumme übereinstimmt
do{
print "30\n";
if($client_socket->can_read($maxTimeout))
{
$socket->recv($Bestaetigung_checksum_daten,16) or warn $!;
}
}while(length($Bestaetigung_checksum_daten) == 0);

print "Bestaetigung_checksum_daten: $Bestaetigung_checksum_daten\n";
print "31\n";

if($Bestaetigung_checksum_daten == 0)
{
for($i = 0; $i<$Anzahl_Pakete; $i++)
{
print "32\n";

while($Bestaetigung_laenge_daten == 0)
{
#Bestaetigung erhalten ob Länge übereinstimmt
do{
if($client_socket->can_read($maxTimeout))
{
$socket->recv($Bestaetigung_laenge_daten,16) or warn $!;
}
}while(length($Bestaetigung_laenge_daten) == 0);

print "Bestaetigung_laenge_daten: $Bestaetigung_laenge_daten\n";
print "33\n";

if($Bestaetigung_laenge_daten == 0)
{
#String trennen und Datenpakete bilden
$data = substr($zip_daten,$Trenn_Anfang,$Trenn_Ende);
$Trenn_Anfang = $Trenn_Ende;
$Trenn_Ende = $Trenn_Ende + 1024;

print "34\n";

#sende Datenpakete zu Server
$socket->send($data) or warn $!;
}

print "35\n";
}

print "36\n";
$data = ();
}
print "37\n";
}
print "38\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 = ();
$data = ();

#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();

View full thread Fehlerfreie Übertragung von Daten (2)