From f6374eb094b73d584c22af8625d87a7c3363b136 Mon Sep 17 00:00:00 2001 From: thibauth Date: Wed, 13 Jul 2011 16:46:43 +0000 Subject: Loop logic in the client. git-svn-id: https://scm.gforge.inria.fr/svn/pacemaker@43 30fcff6e-8de6-41c7-acce-77ff6d1dd07b --- sources/thibaut/Makefile | 4 +- sources/thibaut/client.ml | 138 ++++++++++++++++++++++++-------------- sources/thibaut/clientGlobals.ml | 8 +++ sources/thibaut/clientMesh.ml | 30 +++++++++ sources/thibaut/clientMessages.ml | 0 5 files changed, 126 insertions(+), 54 deletions(-) create mode 100644 sources/thibaut/clientMesh.ml create mode 100644 sources/thibaut/clientMessages.ml diff --git a/sources/thibaut/Makefile b/sources/thibaut/Makefile index 88a23d9..5652865 100644 --- a/sources/thibaut/Makefile +++ b/sources/thibaut/Makefile @@ -3,7 +3,7 @@ OCAMLOPT=ocamlopt OCAMLDEP=ocamldep INCLUDES= OCAMLFLAGS=$(INCLUDES) -annot -SRCS=simulator.ml trace.ml gentrace.ml pacemaker.ml globals.ml compattrace.ml tracestats.ml mesh.ml graph.ml client.ml clientGlobals.ml +SRCS=simulator.ml trace.ml gentrace.ml pacemaker.ml globals.ml compattrace.ml tracestats.ml mesh.ml graph.ml client.ml clientMesh.ml clientGlobals.ml BUILDDIR=build DEPEND=.depend LIBS=str unix @@ -18,7 +18,7 @@ $(BUILDDIR): client: $(BUILDDIR) $(BUILDDIR)/client $(BUILDDIR)/client: client.cmx - $(OCAMLOPT) -o $@ $(OCAMLFLAGS) $(LIBSOPT) clientGlobals.cmx client.cmx + $(OCAMLOPT) -o $@ $(OCAMLFLAGS) $(LIBSOPT) clientGlobals.cmx clientMesh.cmx client.cmx tracestats.opt: $(BUILDDIR) $(BUILDDIR)/tracestats diff --git a/sources/thibaut/client.ml b/sources/thibaut/client.ml index 39aea36..10450f4 100644 --- a/sources/thibaut/client.ml +++ b/sources/thibaut/client.ml @@ -1,5 +1,6 @@ open Unix open ClientGlobals +open ClientMesh let port = ref 54321 let max_length = 10000 @@ -8,13 +9,17 @@ let version = "0.1" let server = ref false let id_file = ref "id.conf" let generate = ref false +let degree = ref 10 +let accuracy = ref 10. let arg_list = Arg.align [ "--port", Arg.Set_int port, " listening port"; "--conf", Arg.Set_string config_file, " configuration file"; "--server", Arg.Set server, " launch the client as a server"; "--id", Arg.Set_string id_file, " id file"; - "--genid", Arg.Set generate, " generate the id file" + "--genid", Arg.Set generate, " generate the id file"; + "--degree", Arg.Set_int degree, " number of neighbours"; + "--accuracy", Arg.Set_float accuracy, " number of minutes between rounds"; ] let usage = Printf.sprintf "usage: %s [OPTIONS]" Sys.argv.(0) @@ -23,22 +28,33 @@ let process_message s = let message = Marshal.from_string s 0 in () +let safe_open f filename = + try + f filename + with + | Sys_error s -> Printf.eprintf "Could not open file: %s.\n" s; exit 1 + +let send_message socket message addr = + let raw = Marshal.to_string message [] in + ignore( sendto + socket (Marshal.to_string message []) + 0 (String.length raw) [] addr + ) + +let init_round time = () +let init_pulse time = () +let seed_reply time = () +let filter_peers () = () let _ = Printf.printf "Pacemaker client v%s\n%!" version; Arg.parse arg_list (fun _ -> ()) usage; - let my_address = (gethostbyname(gethostname())).h_addr_list.(0) in + let my_addr = (gethostbyname(gethostname())).h_addr_list.(0) in - let _ = + let _ = if !generate then begin - let id_oc = - try - open_out !id_file - with - Sys_error s -> Printf.eprintf "The file '%s' could not be opened, %s\n%!" - !id_file s; exit 1 - in + let id_oc = safe_open open_out !id_file in Random.self_init (); Printf.fprintf id_oc "%d" (Random.int 500000000); Printf.printf "Id generated in file %s\n%!" !id_file; @@ -47,65 +63,83 @@ let _ = end in - let id_ic = - try - open_in !id_file - with - Sys_error s -> Printf.eprintf "The file '%s' could not be opened, %s\n%!" - !id_file s; exit 1 - in - + let id_ic = safe_open open_in !id_file in let my_id = Scanf.fscanf id_ic "%d" (fun x -> x) in - - let conf_ic = - try - open_in !config_file - with - Sys_error s -> Printf.eprintf "The file '%s' could not be opened, %s\n%!" - !config_file s; exit 1 - in - - let server_address, server_port = - Scanf.fscanf conf_ic "%s\n%d" (fun a b -> a,b) - in - + let conf_ic = safe_open open_in !config_file in + let root_addr, root_port = Scanf.fscanf conf_ic "%s\n%d" (fun a b -> a,b) in let _ = close_in conf_ic; close_in id_ic in let socket = socket PF_INET SOCK_DGRAM 0 in - let address = ADDR_INET( - my_address, + let addr = ADDR_INET( + my_addr, !port ) in - let server_address = ADDR_INET( - inet_addr_of_string server_address, - server_port + let root_addr = ADDR_INET( + inet_addr_of_string root_addr, + root_port ) in let _ = try - bind socket address + bind socket addr with | Unix_error(e,s1,s2) -> - Printf.eprintf "Could not bind socket on port %d: %s in %s %s\n%!" + Printf.eprintf "Could not bind socket on port %d: %s in %s %s\n%!" !port (error_message e) s1 s2; exit 1 in + + Printf.printf "Now listening on UDP port %d\n%!" !port; + let slot_array = SlotArray.make !degree in + + let reply_tick = 30. in + let mesh_tick = 30. in + let seed_tick = !accuracy/.2. in + let time = Unix.gettimeofday() in + let next_round = ref (time +. !accuracy) in + let next_pulse = ref (!next_round +. seed_tick) in + let next_seed = ref (time +. reply_tick) in + let next_mesh = ref (time +. mesh_tick) in while true do - let a,b,c = select [socket] [] [] 1. in - match a with - | [] -> () - | t::q -> - let buff = String.create max_length in - let len, addr = recvfrom t buff 0 max_length [] in - let addr_string = match addr with - | ADDR_INET(iaddr,port) -> Printf.sprintf "%s:%d" - (string_of_inet_addr iaddr) port - | _ -> "" - in - process_message (String.sub buff 0 len); - Printf.printf "Received from %s: %s\n%!" addr_string - (String.sub buff 0 len) + let time = Unix.gettimeofday() in + + if !server && (time > !next_round) then begin + init_round time; + next_round := time +. !accuracy; + next_pulse := !next_round +. seed_tick; + end; + + if !server && (time > !next_pulse) then begin + init_pulse time; + next_pulse := !next_pulse +. !accuracy; + end; + + if (not !server) && (time > !next_seed) then begin + seed_reply time; + next_seed := !next_seed +. reply_tick + end; + + if time > !next_mesh then begin + next_mesh := !next_mesh +. mesh_tick; + filter_peers (); + end; + + let a,b,c = select [socket] [] [] 1. in + match a with + | [] -> () + | t::q -> + let buff = String.create max_length in + let len, addr = recvfrom t buff 0 max_length [] in + let addr_string = match addr with + | ADDR_INET(iaddr,port) -> Printf.sprintf "%s:%d" + (string_of_inet_addr iaddr) port + | _ -> "" + in + process_message (String.sub buff 0 len); + Printf.printf "Received from %s: %s\n%!" addr_string + (String.sub buff 0 len) + done diff --git a/sources/thibaut/clientGlobals.ml b/sources/thibaut/clientGlobals.ml index be72604..a07715d 100644 --- a/sources/thibaut/clientGlobals.ml +++ b/sources/thibaut/clientGlobals.ml @@ -11,5 +11,13 @@ type message_content = type message = { id : user_id; + version : string; content : message_content; } + +type neighbour = { + id : user_id; + last_seen : float; + addr : sockaddr; +} + diff --git a/sources/thibaut/clientMesh.ml b/sources/thibaut/clientMesh.ml new file mode 100644 index 0000000..6a63017 --- /dev/null +++ b/sources/thibaut/clientMesh.ml @@ -0,0 +1,30 @@ +open ClientGlobals + +module SlotArray : sig + type t + type slot = Peer of neighbour | Empty + val make : int -> t + val full : t -> bool +end = struct + + type slot = Peer of neighbour | Empty + + type t = { + capacity : int; + mutable length : int; + array : slot array + } + + let make degree = { + capacity = degree; + length = 0; + array = Array.make degree Empty + } + + let full sa = sa.length = sa.capacity + + let add sa neighbour = + let length = sa.length in + if not (full sa) then + sa.array.(length) <- neighbour +end diff --git a/sources/thibaut/clientMessages.ml b/sources/thibaut/clientMessages.ml new file mode 100644 index 0000000..e69de29 -- cgit v1.2.3-70-g09d2