Bücher online kostenlos Kostenlos Online Lesen
Die Programmiersprache Ruby (German Edition)

Die Programmiersprache Ruby (German Edition)

Titel: Die Programmiersprache Ruby (German Edition) Kostenlos Bücher Online Lesen
Autoren: David Flanagan , Yukihiro Matsumoto
Vom Netzwerk:
von
recvfrom
legt die maximale Datenmenge fest, die wir empfangen wollen. In diesem Fall begrenzen wir unseren Client und Server auf eine maximale Übertragung von einem Kilobyte:
require 'socket' # Standardbibliothek
host, port, request = ARGV # Argumente von der Befehlszeile holen
ds = UDPSocket.new # Datagramm-Socket erzeugen
ds.connect(host, port) # Mit dem Port auf dem Host verbinden
ds.send(request, 0) # Text schicken
response,address = ds.recvfrom(1024) # Auf Antwort warten (maximal 1 KB)
puts response # Antwort ausgeben
    Der Servercode nutzt die Klasse
UDPSocket
genauso wie der Clientcode – es gibt keine spezielle
UDPServer
-Klasse für datagrammbasierte Server. Statt
connect
für die Verbindung des Sockets aufzurufen, nutzt unserer Server
bind
, um dem Socket mitzuteilen, an welchem Port er zu lauschen hat. Der Server verwendet dann
send
und
recvfrom
so wie der Client, aber in umgekehrter Reihenfolge. Er ruft
recvfrom
auf, um zu warten, bis er ein Datagramm am angegebenen Port erhält. Wenn das geschieht, wandelt der Server den empfangenen Text in Großbuchstaben um und schickt ihn zurück. Zu beachten ist, dass die Methode
recvfrom
zwei Werte zurückgibt. Der erste enthält die empfangenen Daten. Der zweite ist ein Array, das Informationen darüber enthält, woher die Daten gekommen sind. Wir extrahieren die Host- und Portinformationen aus diesem Array und verwenden sie, um die Antwort an den Client zurückzuschicken:
require 'socket' # Standardbibliothek
port = ARGV[0] # Port, an dem gelauscht werden soll
ds = UDPSocket.new # Neuen Socket erzeugen
ds.bind(nil, port) # Am Port lauschen lassen
loop do # Unendliche Schleife
request,address=ds.recvfrom(1024) # Darauf warten, dass etwas kommt
response = request.upcase # Text in Großbuchstaben umwandeln
clientaddr = address[3] # Welche IP-Adresse hat die Anfrage geschickt?
clientname = address[2] # Wie ist der Hostname?
clientport = address[1] # Von welchem Port kam sie?
ds.send(response, 0, # Schicke die Antwort dorthin,
     clientaddr, clientport) # wo die Anfrage herkam
# Verbindung mit dem Client protokollieren
puts "Verbindung von: #{clientname} #{clientaddr} #{clientport}"
end
    9.8.4 Ein komplexerer Client
    Der folgende Code ist ein umfassender entwickelter Internetclient im Stil von telnet . Er verbindet sich mit dem angegebenen Host und Port und läuft dann in einer Schleife, in der er eine Eingabezeile von der Konsole liest, sie an den Server schickt und dann die Antwort des Servers einliest und ausgibt. Der Client zeigt, wie man die lokalen und entfernten Adressen der Netzwerkverbindung ermittelt, enthält Exception-Handling und verwendet die
IO
-Methoden
read_nonblock
und
readpartial
, die weiter oben in diesem Kapitel beschrieben wurden. Der Code ist umfassend dokumentiert und sollte selbsterklärend sein:
require 'socket' # Sockets aus der Standardbibliothek
host, port = ARGV # Netzwerkhost und -port von der Befehlszeile

begin # Begin für Exception-Handling
# Feedback an den Benutzer, während die Verbindung aufgebaut wird
STDOUT.print "Connecting..." # Erzählen, was wir tun
STDOUT.flush # Direkt ausgeben
s = TCPSocket.open(host, port) # Verbinden
STDOUT.puts "done" # Und sagen, dass wir es getan haben

# Jetzt Informationen über die Verbindung anzeigen
local, peer = s.addr, s.peeraddr
STDOUT.print "Verbunden mit #{peer[2]}:#{peer[1]}"
STDOUT.puts " über den lokalen Port #{local[1]}"

# Ein bisschen warten, um zu sehen, ob der Server eine initiale Nachricht schickt
begin
    sleep(0.5) # Eine halbe Sekunde warten
    msg = s.read_nonblock(4096) # Alles lesen, was schon da ist
    STDOUT.puts msg.chop # Und anzeigen
rescue SystemCallError
    # Wenn nichts zu lesen da war, die Exception einfach ignorieren
end

# Nun eine Schleife für die Client/Server-Interaktion beginnen
loop do
    STDOUT.print '> ' # Prompt für die lokale Eingabe anzeigen
    STDOUT.flush # Sicherstellen, dass die Ausgabe sichtbar ist
    local = STDIN.gets # Zeile von der Konsole lesen
    break if !local # Beenden, wenn keine Eingabe von der Konsole kommt

    s.puts(local) # Die Zeile an den Server schicken
    s.flush # Ausgabe erzwingen

    # Antwort des Servers lesen und ausgeben.
    # Der Server kann mehr als eine Zeile schicken; daher readpartial nutzen,
    # um alles zu lesen, was er schickt (solange alles in einem Stück kommt)
    response = s.readpartial(4096) # Antwort des Servers lesen
    puts(response.chop) # Antwort ausgeben
end
rescue # Wenn etwas schiefgeht,
puts $! #

Weitere Kostenlose Bücher