Thread Fehlerfreie Übertragung von Daten (2)
(9 answers)
Opened by
ITobiI
at 2015-10-15 19:46
User since 2015-09-10
70
Artikel
BenutzerIn
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:
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();
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)
|