AVS Aufgabe 1 - Verteilte Systeme

Werbung
Musterlösung Aufgabe 1.1/1.2: server
#!/usr/bin/perl
use Socket;
use Sys::Hostname;
use Time::HiRes qw(gettimeofday);
my $port = shift @ARGV || 12345;
my $iaddr = gethostbyname(hostname());
my $proto = getprotobyname(’udp’);
my $paddr = sockaddr_in($port, $iaddr);
socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) || die "socket: $!";
bind(SOCKET, $paddr)
|| die "bind: $!";;
while(1) {
my ($msg, $hisaddr, $hisport, $hisiaddr);
($hisaddr = recv(SOCKET, $msg, 8, 0)) || die("recv: $!");
my $repl = $msg . pack("L2", gettimeofday);
send(SOCKET, $repl, 0, $hisaddr)
}
Hans P. Reiser (Abteilung Verteilte Systeme)
AVS Aufgabe 1
4. November 2005
1/7
Musterlösung Aufgabe 1.1/1.2: client (1/2)
#!/usr/bin/perl
use Socket;
use Sys::Hostname;
use Time::HiRes qw(gettimeofday);
# Parse command line arguments
my $host = shift @ARGV || ’localhost’;
my $port = shift @ARGV || 12345;
my $hishost = gethostbyname($host) or die "gethostbyname $host: $!";
# Create local socket
my $proto = getprotobyname(’udp’);
my $iaddr = gethostbyname(hostname());
my $paddr = sockaddr_in(0, $iaddr);
socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) || die "socket: $!";
bind(SOCKET, $paddr)
|| die "bind: $!";
Hans P. Reiser (Abteilung Verteilte Systeme)
AVS Aufgabe 1
4. November 2005
2/7
Musterlösung Aufgabe 1.1/1.2: client (2/2)
# Send probe message
my $hisaddr = sockaddr_in($port, $hishost);
my $msg = pack("L2", gettimeofday);
send(SOCKET, $msg, 0, $hisaddr);
# Wait for reply, process reply
my $repl;
($hisaddr = recv(SOCKET, $repl, 16, 0)) || die("recv: $!");
my $t3 = time();
my $t1 = timedecode(substr($repl,0,8));
my $t2 = timedecode(substr($repl,8,8));
printf("Offset: %.3f +/- %.3f\n", ($t3+$t1)/2-$t2, ($t3-$t1)/2);
sub timedecode {
my $str = shift;
my ($sec, $usec) = unpack("L2",$str);
return $sec + 0.000001 * $usec;
}
Hans P. Reiser (Abteilung Verteilte Systeme)
AVS Aufgabe 1
4. November 2005
3/7
Lösung in Java: server
import java.io.*;
import java.net.*;
public class server {
public static void main(String[] args) {
long currentTime;
int port = Integer.parseInt(args[0]);
try {
ServerSocket connectionSocket = new ServerSocket( port );
} catch ( IOException ioex ) {
System.out.println("Cannot create server socket: "+ioex);
System.exit(-1);
}
while(true){ // Warten auf Clienten
try {
Socket client = connectionSocket.accept();
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
BufferedReader in = new BufferedReader( new InputStreamReader(
client.getInputStream() ) );
String command = in.readLine();
if ( command.compareTo("Time")==0 ) {
out.println(System.currentTimeMillis());
}
}
catch ( IOException ioex ) {
System.out.println("Failed: "+ioex.getClass()+": "+ioex.toString());
System.exit(-1);
}
}
}
}
Hans P. Reiser (Abteilung Verteilte Systeme)
AVS Aufgabe 1
4. November 2005
4/7
Lösung in Java: client (1/2)
import java.io.*;
import java.net.*;
public class client {
public static void main(String[] args) {
PrintWriter out = null;
BufferedReader in = null;
try {
// Sockets erzeugen, Streams anlegen
Socket s = new Socket( args[0], Integer.parseInt(args[1]) );
out = new PrintWriter(s.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
s.getInputStream()));
} catch (Exception e) {
System.err.println("Cannot create socket: "+e);
System.exit(1);
}
// Erst lokale Zeit abfragen, dann Anfrage an Server
long t1 = System.currentTimeMillis();
out.println("Time");
Hans P. Reiser (Abteilung Verteilte Systeme)
AVS Aufgabe 1
4. November 2005
5/7
Lösung in Java: Client (2/2)
try { // Auf Antwort von Server warten und diese verarbeiten.
String receivedData = in.readLine();
long t3 = System.currentTimeMillis();
long t2 = Long.parseLong(receivedData);
// Maximalen Fehler ausrechnen
long maxDist = t3 - t1;
double offset = ( (t1-t2)+(t3-t2) )/2;
// Ergebnis ausgeben
System.out.println("Offset: " + offset*0.001 + "s +/-" +
maxDist*0.001 + "s");
}
catch( IOException ioex ){//Fehlerbehandlung
System.exit(-1);
}
System.exit(0);
}
}
Hans P. Reiser (Abteilung Verteilte Systeme)
AVS Aufgabe 1
4. November 2005
6/7
Uhrenmanipulation
libtimemagic auf Homepage
export
export
export
export
export
LD_PRELOAD=/<...>/libtimemagic.so.0.0
TIMEMAGIC_VERBOSE=1
[optional]
TIMEMAGIC_OFFSET=100
[in Sekunden]
TIMEMAGIC_DRIFT=1000
[in ppm]
TIMEMAGIC_REF=‘perl -e "print time"‘
[Epoch-Sekunden
date
bin/client ...
...
Hans P. Reiser (Abteilung Verteilte Systeme)
AVS Aufgabe 1
4. November 2005
7/7
Herunterladen