This commit is contained in:
Ingy döt Net 2013-04-10 16:57:12 -07:00
parent 518da4a923
commit 764da6cbbb
6144 changed files with 83610 additions and 11 deletions

View file

@ -0,0 +1,5 @@
Write two programs (or one program with two modes) which run on networked computers, and send some messages between them.
The protocol used may be language-specific or not, and should be '''suitable for general distributed programming'''; that is, the ''protocol'' should be generic (not designed just for the particular example application), readily capable of handling the independent communications of many different components of a single application, and the transferring of arbitrary data structures natural for the language.
This task is intended to demonstrate high-level communication facilities beyond just creating [[sockets]].

View file

@ -0,0 +1,2 @@
---
note: Networking and Web Interaction

View file

@ -0,0 +1,5 @@
package Server is
pragma Remote_Call_Interface;
procedure Foo;
function Bar return Natural;
end Server;

View file

@ -0,0 +1,13 @@
package body Server is
Count : Natural := 0;
procedure Foo is
begin
Count := Count + 1;
end Foo;
function Bar return Natural is
begin
return Count;
end Bar;
end Server;

View file

@ -0,0 +1,9 @@
with Server;
with Ada.Text_IO;
procedure Client is
begin
Ada.Text_IO.Put_Line ("Calling Foo...");
Server.Foo;
Ada.Text_IO.Put_Line ("Calling Bar: " & Integer'Image (Server.Bar));
end Client;

View file

@ -0,0 +1,13 @@
configuration DSA is
pragma Starter (None);
-- Server
Server_Partition : Partition := (Server);
procedure Run_Server is in Server_Partition;
-- Client
Client_Partition : Partition;
for Client_Partition'Termination use Local_Termination;
procedure Client;
for Client_Partition'Main use Client;
end DSA;

View file

@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <pvm3.h>
int main(int c, char **v)
{
int tids[10];
int parent, spawn;
int i_data, i2;
double f_data;
if (c > 1) {
spawn = pvm_spawn("/tmp/a.out", 0, PvmTaskDefault, 0, 1, tids);
if (spawn <= 0) {
printf("Can't spawn task\n");
return 1;
}
printf("Spawning successful\n");
/* pvm_recv(task_id, msgtag). msgtag identifies what kind of data it is,
* for here: 1 = (int, double), 2 = (int, int)
* The receiving order is intentionally swapped, just to show.
* task_id = -1 means "receive from any task"
*/
pvm_recv(-1, 2);
pvm_unpackf("%d %d", &i_data, &i2);
printf("got msg type 2: %d %d\n", i_data, i2);
pvm_recv(-1, 1);
pvm_unpackf("%d %lf", &i_data, &f_data);
printf("got msg type 1: %d %f\n", i_data, f_data);
} else {
parent = pvm_parent();
pvm_initsend(PvmDataDefault);
i_data = rand();
f_data = (double)rand() / RAND_MAX;
pvm_packf("%d %lf", i_data, f_data);
pvm_send(parent, 1); /* send msg type 1 */
pvm_initsend(PvmDataDefault);
i2 = rand();
pvm_packf("%d %d", i_data, i2);
pvm_send(parent, 2); /* send msg type 2 */
}
pvm_exit();
return 0;
}

View file

@ -0,0 +1,11 @@
pvm> spawn -> /tmp/a.out 1
spawn -> /tmp/a.out 1
[2]
1 successful
t40028
pvm> [2:t40029] EOF
[2:t40028] Spawning successful
[2:t40028] got msg type 2: 1804289383 1681692777
[2:t40028] got msg type 1: 1804289383 0.394383
[2:t40028] EOF
[2] finished

View file

@ -0,0 +1,38 @@
module distributedserver ;
import tango.net.ServerSocket, tango.text.convert.Integer,
tango.text.Util, tango.io.Stdout ;
void main() {
auto Ip = new InternetAddress("localhost", 12345) ;
auto server = new ServerSocket(Ip) ;
auto socket = server.accept ;
auto buffer = new char[socket.bufferSize] ;
bool quit = false ;
while(!quit) {
bool error = false ;
try {
auto len = socket.input.read(buffer) ;
auto cmd = (len > 0) ? delimit(buffer[0..len], " ") : [""] ;
Stdout(cmd).newline.flush ;
switch (cmd[0]) {
case "square":
socket.output.write(toString(toInt(cmd[1]) * toInt(cmd[1]))) ; break ;
case"add":
socket.output.write(toString(toInt(cmd[1]) + toInt(cmd[2]))) ; break ;
case "quit":
socket.output.write("Server Shut down") ;
quit = true ; break ;
default: error = true ;
}
} catch (Exception e)
error = true ;
if(error) socket.output.write("<Error>") ;
if(socket) socket.close ;
if(!quit) socket = server.accept ;
}
if(socket) socket.close ;
}

View file

@ -0,0 +1,24 @@
module distributedclient ;
import tango.net.SocketConduit, tango.net.InternetAddress,
tango.text.Util, tango.io.Stdout ;
void main(char[][] args) {
if(args.length> 1) {
try {
auto Ip = new InternetAddress("localhost", 12345) ;
auto socket = new SocketConduit ;
socket.connect(Ip) ;
auto buffer = new char[socket.bufferSize] ;
socket.output.write(join(args[1..$]," ")) ;
auto len = socket.input.read(buffer) ;
if(len > 0) Stdout(buffer[0..len]).newline ;
if(socket) socket.close ;
} catch(Exception e)
Stdout(e.msg).newline ;
} else
Stdout("usage: supply argument as,\n\tquit\n"
"\tsquare <number>\n\tadd <number> <number>").newline ;
}

View file

@ -0,0 +1,19 @@
def storage := [].diverge()
def logService {
to log(line :String) {
storage.push([timer.now(), line])
}
to search(substring :String) {
var matches := []
for [time, line] ? (line.startOf(substring) != -1) in storage {
matches with= [time, line]
}
return matches
}
}
introducer.onTheAir()
def sturdyRef := makeSturdyRef.temp(logService)
println(<captp>.sturdyToURI(sturdyRef))
interp.blockAtTop()

View file

@ -0,0 +1,14 @@
def [uri] := interp.getArgs()
introducer.onTheAir()
def sturdyRef := <captp>.sturdyFromURI(uri)
def logService := sturdyRef.getRcvr()
logService <- log("foot")
logService <- log("shoe")
println("Searching...")
when (def result := logService <- search("foo")) -> {
for [time, line] in result {
println(`At $time: $line`)
}
}

View file

@ -0,0 +1,19 @@
-module(srv).
-export([start/0, wait/0]).
start() ->
net_kernel:start([srv,shortnames]),
erlang:set_cookie(node(), rosetta),
Pid = spawn(srv,wait,[]),
register(srv,Pid),
io:fwrite("~p ready~n",[node(Pid)]),
ok.
wait() ->
receive
{echo, Pid, Any} ->
io:fwrite("-> ~p from ~p~n", [Any, node(Pid)]),
Pid ! {hello, Any},
wait();
Any -> io:fwrite("Error ~p~n", [Any])
end.

View file

@ -0,0 +1,17 @@
-module(client).
-export([start/0, wait/0]).
start() ->
net_kernel:start([client,shortnames]),
erlang:set_cookie(node(), rosetta),
{ok,[[Srv]]} = init:get_argument(server),
io:fwrite("connecting to ~p~n", [Srv]),
{srv, list_to_atom(Srv)} ! {echo,self(), hi},
wait(),
ok.
wait() ->
receive
{hello, Any} -> io:fwrite("Received ~p~n", [Any]);
Any -> io:fwrite("Error ~p~n", [Any])
end.

View file

@ -0,0 +1,30 @@
package main
import (
"errors"
"log"
"net"
"net/http"
"net/rpc"
)
type TaxComputer float64
func (taxRate TaxComputer) Tax(x float64, r *float64) error {
if x < 0 {
return errors.New("Negative values not allowed")
}
*r = x * float64(taxRate)
return nil
}
func main() {
c := TaxComputer(.05)
rpc.Register(c)
rpc.HandleHTTP()
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal(err)
}
http.Serve(listener, nil)
}

View file

@ -0,0 +1,23 @@
package main
import (
"fmt"
"log"
"net/rpc"
)
func main() {
client, err := rpc.DialHTTP("tcp", "localhost:1234")
if err != nil {
fmt.Println(err)
return
}
amount := 3.
var tax float64
err = client.Call("TaxComputer.Tax", amount, &tax)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Tax on %.2f: %.2f\n", amount, tax)
}

View file

@ -0,0 +1,8 @@
var net = require('net')
var server = net.createServer(function (c){
c.write('hello\r\n')
c.pipe(c) // echo messages back
})
server.listen(3000, 'localhost')

View file

@ -0,0 +1,12 @@
var net = require('net')
conn = net.createConnection(3000, '192.168.1.x')
conn.on('connect', function(){
console.log('connected')
conn.write('test')
})
conn.on('data', function(msg){
console.log(msg.toString())
})

View file

@ -0,0 +1,43 @@
use Data::Dumper;
use IO::Socket::INET;
use Safe;
sub get_data {
my $sock = new IO::Socket::INET
LocalHost => "localhost",
LocalPort => "10000",
Proto => "tcp",
Listen => 1,
Reuse => 1;
unless ($sock) { die "Socket creation failure" }
my $cli = $sock->accept();
# of course someone may be tempted to send you 'system("rm -rf /")',
# to be safe(r), use Safe::
my $safe = new Safe;
my $x = $safe->reval(join("", <$cli>));
close $cli;
close $sock;
return $x;
}
sub send_data {
my $host = shift;
my $data = shift;
my $sock = new IO::Socket::INET
PeerAddr => "$host:10000",
Proto => "tcp",
Reuse => 1;
unless ($sock) { die "Socket creation failure" }
print $sock Data::Dumper->Dump([$data]);
close $sock;
}
if (@ARGV) {
my $x = get_data();
print "Got data\n", Data::Dumper->Dump([$x]);
} else {
send_data('some_host', { a=>100, b=>[1 .. 10] });
}

View file

@ -0,0 +1,9 @@
(task (port 12321) # Background server task
(let? Sock (accept @)
(unless (fork) # Handle request in child process
(in Sock
(while (rd) # Handle requests
(out Sock
(pr (eval @)) ) ) ) # Evaluate and send reply
(bye) ) # Exit child process
(close Sock) ) ) # Close socket in parent process

View file

@ -0,0 +1,6 @@
(let? Sock (connect "localhost" 12321)
(out Sock (pr '*Pid)) # Query PID from server
(println 'PID (in Sock (rd))) # Receive and print reply
(out Sock (pr '(* 3 4))) # Request some calculation
(println 'Result (in Sock (rd))) # Print result
(close Sock) ) # Close connection to server

View file

@ -0,0 +1,38 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import SimpleXMLRPCServer
class MyHandlerInstance:
def echo(self, data):
'''Method for returning data got from client'''
return 'Server responded: %s' % data
def div(self, num1, num2):
'''Method for divide 2 numbers'''
return num1/num2
def foo_function():
'''A function (not an instance method)'''
return True
HOST = "localhost"
PORT = 8000
server = SimpleXMLRPCServer.SimpleXMLRPCServer((HOST, PORT))
# register built-in system.* functions.
server.register_introspection_functions()
# register our instance
server.register_instance(MyHandlerInstance())
# register our function as well
server.register_function(foo_function)
try:
# serve forever
server.serve_forever()
except KeyboardInterrupt:
print 'Exiting...'
server.server_close()

View file

@ -0,0 +1,12 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import spread
PORT = '4803'
conn = spread.connect(PORT)
conn.join('test')
conn.multicast(spread.RELIABLE_MESS, 'test', 'hello, this is message sent from python')
conn.disconnect()

View file

@ -0,0 +1,23 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import xmlrpclib
HOST = "localhost"
PORT = 8000
rpc = xmlrpclib.ServerProxy("http://%s:%d" % (HOST, PORT))
# print what functions does server support
print 'Server supports these functions:',
print ' '.join(rpc.system.listMethods())
# echo something
rpc.echo("We sent this data to server")
# div numbers
print 'Server says: 8 / 4 is: %d' % rpc.div(8, 4)
# control if foo_function returns True
if rpc.foo_function():
print 'Server says: foo_function returned True'

View file

@ -0,0 +1,30 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import BaseHTTPServer
HOST = "localhost"
PORT = 8000
# we just want to write own class, we replace do_GET method. This could be extended, I just added basics
# see; http://docs.python.org/lib/module-BaseHTTPServer.html
class MyHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
# send 200 (OK) message
self.send_response(200)
# send header
self.send_header("Content-type", "text/html")
self.end_headers()
# send context
self.wfile.write("<html><head><title>Our Web Title</title></head>")
self.wfile.write("<body><p>This is our body. You wanted to visit <b>%s</b> page</p></body>" % self.path)
self.wfile.write("</html>")
if __name__ == '__main__':
server = BaseHTTPServer.HTTPServer((HOST, PORT), MyHTTPHandler)
try:
server.serve_forever()
except KeyboardInterrupt:
print 'Exiting...'
server.server_close()

View file

@ -0,0 +1,15 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import httplib
HOST = "localhost"
PORT = 8000
conn = httplib.HTTPConnection(HOST, PORT)
conn.request("GET", "/somefile")
response = conn.getresponse()
print 'Server Status: %d' % response.status
print 'Server Message: %s' % response.read()

View file

@ -0,0 +1,57 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import SocketServer
import pickle
HOST = "localhost"
PORT = 8000
class RPCServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
# The object_to_proxy member should be set to the object we want
# methods called on. Unfortunately, we can't do this in the constructor
# because the constructor should not be overridden in TCPServer...
daemon_threads = True
class RPCHandler(SocketServer.StreamRequestHandler):
def handle(self):
in_channel = pickle.Unpickler(self.rfile)
out_channel = pickle.Pickler(self.wfile, protocol=2)
while True:
try:
name, args, kwargs = in_channel.load()
print 'got %s %s %s' % (name, args, kwargs)
except EOFError:
# EOF means we're done with this request.
# Catching this exception to detect EOF is a bit hackish,
# but will work for a quick demo like this
break
try:
method = getattr(self.server.object_to_proxy, name)
result = method(*args, **kwargs)
except Exception, e:
out_channel.dump(('Error',e))
else:
out_channel.dump(('OK',result))
class MyHandlerInstance(object):
def echo(self, data):
'''Method for returning data got from client'''
return 'Server responded: %s' % data
def div(self, dividend, divisor):
'''Method to divide 2 numbers'''
return dividend/divisor
def is_computer_on(self):
return True
if __name__ == '__main__':
rpcserver = RPCServer((HOST, PORT), RPCHandler)
rpcserver.object_to_proxy = MyHandlerInstance()
try:
rpcserver.serve_forever()
except KeyboardInterrupt:
print 'Exiting...'
rpcserver.server_close()

View file

@ -0,0 +1,55 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket
import pickle
HOST = "localhost"
PORT = 8000
class RPCClient(object):
def __init__(self, host, port):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((host, port))
self.rfile = self.socket.makefile('rb')
self.wfile = self.socket.makefile('wb')
self.in_channel = pickle.Unpickler(self.rfile)
self.out_channel = pickle.Pickler(self.wfile, protocol=2)
def _close(self):
self.socket.close()
self.rfile.close()
self.wfile.close()
# Make calling remote methods easy by overriding attribute access.
# Accessing any attribute on our instances will give a proxy method that
# calls the method with the same name on the remote machine.
def __getattr__(self, name):
def proxy(*args, **kwargs):
self.out_channel.dump((name, args, kwargs))
self.wfile.flush() # to make sure the server won't wait forever
status, result = self.in_channel.load()
if status == 'OK':
return result
else:
raise result
return proxy
if __name__ == '__main__':
# connect to server and send data
rpcclient = RPCClient(HOST, PORT)
print 'Testing the echo() method:'
print rpcclient.echo('Hello world!')
print
print 'Calculating 42/2 on the remote machine:'
print rpcclient.div(42, 2)
print
print 'is_computer_on on the remote machine returns:'
print rpcclient.is_computer_on()
print
print 'Testing keyword args:'
print '42/2 is:', rpcclient.div(divisor=2, dividend=42)
rpcclient._close()
del rpcclient

View file

@ -0,0 +1,26 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Pyro.core
import Pyro.naming
# create instance that will return upper case
class StringInstance(Pyro.core.ObjBase):
def makeUpper(self, data):
return data.upper()
class MathInstance(Pyro.core.ObjBase):
def div(self, num1, num2):
return num1/num2
if __name__ == '__main__':
server = Pyro.core.Daemon()
name_server = Pyro.naming.NameServerLocator().getNS()
server.useNameServer(name_server)
server.connect(StringInstance(), 'string')
server.connect(MathInstance(), 'math')
try:
server.requestLoop()
except KeyboardInterrupt:
print 'Exiting...'
server.shutdown()

View file

@ -0,0 +1,17 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import Pyro.core
DATA = "my name is eren"
NUM1 = 10
NUM2 = 5
string = Pyro.core.getProxyForURI("PYRONAME://string")
math = Pyro.core.getProxyForURI("PYRONAME://math")
print 'We sent: %s' % DATA
print 'Server responded: %s\n' % string.makeUpper(DATA)
print 'We sent two numbers to divide: %d and %d' % (NUM1, NUM2)
print 'Server responded the result: %s' % math.div(NUM1, NUM2)

View file

@ -0,0 +1,18 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import spread
PORT = '4803'
# connect spread daemon
conn = spread.connect(PORT)
# join the room
conn.join('test')
print 'Waiting for messages... If you want to stop this script, please stop spread daemon'
while True:
recv = conn.receive()
if hasattr(recv, 'sender') and hasattr(recv, 'message'):
print 'Sender: %s' % recv.sender
print 'Message: %s' % recv.message

View file

@ -0,0 +1,21 @@
require 'drb/drb'
# The URI for the server to connect to
URI="druby://localhost:8787"
class TimeServer
def get_current_time
return Time.now
end
end
# The object that handles requests on the server
FRONT_OBJECT = TimeServer.new
$SAFE = 1 # disable eval() and friends
DRb.start_service(URI, FRONT_OBJECT)
# Wait for the drb server thread to finish before exiting.
DRb.thread.join

View file

@ -0,0 +1,14 @@
require 'drb/drb'
# The URI to connect to
SERVER_URI = "druby://localhost:8787"
# Start a local DRbServer to handle callbacks.
#
# Not necessary for this small example, but will be required
# as soon as we pass a non-marshallable object as an argument
# to a dRuby call.
DRb.start_service
timeserver = DRbObject.new_with_uri(SERVER_URI)
puts timeserver.get_current_time

View file

@ -0,0 +1,63 @@
proc main {} {
global connections
set connections [dict create]
socket -server handleConnection 12345
vwait dummyVar ;# enter the event loop
}
proc handleConnection {channel clientaddr clientport} {
global connections
dict set connections $channel address "$clientaddr:$clientport"
fconfigure $channel -buffering line
fileevent $channel readable [list handleMessage $channel]
}
proc handleMessage {channel} {
global connections
if {[gets $channel line] == -1} {
disconnect $channel
} else {
if {[string index [string trimleft $line] 0] eq "/"} {
set words [lassign [split [string trim $line]] command]
handleCommand $command $words $channel
} else {
echo $line $channel
}
}
}
proc disconnect {channel} {
global connections
dict unset connections $channel
fileevent $channel readable ""
close $channel
}
proc handleCommand {command words channel} {
global connections
switch -exact -- [string tolower $command] {
/nick {
dict set connections $channel nick [lindex $words 0]
}
/quit {
echo bye $channel
disconnect $channel
}
default {
puts $channel "\"$command\" not implemented"
}
}
}
proc echo {message senderchannel} {
global connections
foreach channel [dict keys $connections] {
if {$channel ne $senderchannel} {
set time [clock format [clock seconds] -format "%T"]
set nick [dict get $connections $channel nick]
puts $channel [format "\[%s\] %s: %s" $time $nick $message]
}
}
}
main

View file

@ -0,0 +1,36 @@
proc main {} {
global argv argc
if {$argc != 2} {
error "usage: [info script] serveraddress serverport"
}
connect {*}$argv
vwait dummyVar
}
proc connect {addr port} {
global sock
set sock [socket $addr $port]
fconfigure $sock -buffering line
fileevent $sock readable getFromServer
fileevent stdin readable sendToServer
}
proc getFromServer {} {
global sock
if {[gets $sock line] == -1} {
puts "disconnected..."
exit
} else {
puts $line
}
}
proc sendToServer {} {
global sock
set msg [string trim [gets stdin]]
if {[string length $msg] > 0} {
puts $sock $msg
}
}
main