PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/relay/relay.ml

http://github.com/jaked/lwt-equeue
OCaml | 57 lines | 34 code | 8 blank | 15 comment | 3 complexity | f3b28308f0b621779cdd797f6213bba9 MD5 | raw file
  1. (* Usage: relay <listening_port> <dest_port> *)
  2. (* This program waits for a connection on <listening_port>. It then
  3. connect to <dest_port> and relay everything it receives in either
  4. side to the other side. It exits when either side closes the
  5. connection. *)
  6. let listening_port = int_of_string Sys.argv.(1)
  7. let dest_port = int_of_string Sys.argv.(2)
  8. open Lwt
  9. let rec really_write out_ch buffer pos len =
  10. Lwt_unix.write out_ch buffer pos len >>= (fun len' ->
  11. if len = len' then return () else
  12. really_write out_ch buffer (pos + len') (len - len'))
  13. let relay in_ch out_ch =
  14. let rec relay_rec previous_write =
  15. let buffer = String.create 8192 in
  16. (* Read some data from the input socket *)
  17. Lwt_unix.read in_ch buffer 0 8192 >>= (fun len ->
  18. (* If we read nothing, this means that the connection has been
  19. closed. In this case, we stop relaying. *)
  20. if len = 0 then return () else begin
  21. (* Otherwise, we write the data to the ouput socket *)
  22. let write =
  23. (* First wait for the previous write to terminate *)
  24. previous_write >>= (fun () ->
  25. (* Then write the contents of the buffer *)
  26. really_write out_ch buffer 0 len)
  27. in
  28. relay_rec write
  29. end)
  30. in
  31. relay_rec (return ())
  32. let new_socket () = Lwt_unix.socket Unix.PF_INET Unix.SOCK_STREAM 0
  33. let local_addr num = Unix.ADDR_INET (Unix.inet_addr_any, num)
  34. let _ =
  35. Lwt_equeue.set_event_system (Unixqueue.create_unix_event_system ());
  36. Lwt_unix.run begin
  37. (* Initialize the listening address *)
  38. let listening_socket = new_socket () in
  39. Lwt_unix.setsockopt listening_socket Unix.SO_REUSEADDR true;
  40. Lwt_unix.bind listening_socket (local_addr listening_port);
  41. Lwt_unix.listen listening_socket 1024;
  42. (* Wait for a connection *)
  43. Lwt_unix.accept listening_socket >>= fun (inp, _) ->
  44. (* Connect to the destination port *)
  45. let out = new_socket () in
  46. Lwt_unix.connect out (local_addr dest_port) >>= fun () ->
  47. (* Start relaying *)
  48. Lwt.choose [relay inp out; relay out inp]
  49. end