mirror of
https://github.com/c-cube/linol.git
synced 2025-12-11 21:48:54 -05:00
76 lines
2.5 KiB
OCaml
76 lines
2.5 KiB
OCaml
open! Stdune
|
|
open Fiber.O
|
|
open Lev_fiber
|
|
|
|
let%expect_test "server & client" =
|
|
let path = "levfiber.sock" in
|
|
(try Unix.unlink path with Unix.Unix_error _ -> ());
|
|
let server_sockaddr =
|
|
if Sys.win32 then Unix.ADDR_INET (Unix.inet_addr_loopback, 0)
|
|
else Unix.ADDR_UNIX path
|
|
in
|
|
let domain = Unix.domain_of_sockaddr server_sockaddr in
|
|
let socket () =
|
|
Lev_fiber.Fd.create
|
|
(Unix.socket ~cloexec:true domain Unix.SOCK_STREAM 0)
|
|
(`Non_blocking false)
|
|
in
|
|
let client_sockaddr = Fiber.Ivar.create () in
|
|
let run () =
|
|
let ready_client = Fiber.Ivar.create () in
|
|
let server () =
|
|
print_endline "server: starting";
|
|
let fd = socket () in
|
|
let unix_fd = Lev_fiber.Fd.fd_exn fd in
|
|
Unix.setsockopt unix_fd Unix.SO_REUSEADDR true;
|
|
let* server = Socket.Server.create fd server_sockaddr ~backlog:10 in
|
|
let* () = Fiber.Ivar.fill client_sockaddr (Unix.getsockname unix_fd) in
|
|
print_endline "server: created";
|
|
let* () = Fiber.Ivar.fill ready_client () in
|
|
print_endline "server: serving";
|
|
Socket.Server.serve server ~f:(fun session ->
|
|
let* i, o = Socket.Server.Session.io session in
|
|
print_endline "server: client connected";
|
|
let* contents = Io.with_read i ~f:Io.Reader.to_string in
|
|
printfn "server: received %S" contents;
|
|
let* () =
|
|
Io.with_write o ~f:(fun w ->
|
|
Io.Writer.add_string w "pong";
|
|
Io.Writer.flush w)
|
|
in
|
|
Io.close o;
|
|
Io.close i;
|
|
Socket.Server.close server)
|
|
in
|
|
let client () =
|
|
let* () = Fiber.Ivar.read ready_client in
|
|
let fd = socket () in
|
|
print_endline "client: starting";
|
|
let* sockaddr = Fiber.Ivar.read client_sockaddr in
|
|
let* () = Socket.connect fd sockaddr in
|
|
print_endline "client: successfully connected";
|
|
let* i, o = Io.create_rw fd in
|
|
let* () =
|
|
Io.with_write o ~f:(fun w ->
|
|
Io.Writer.add_string w "ping";
|
|
Io.Writer.flush w)
|
|
in
|
|
Unix.shutdown (Lev_fiber.Fd.fd_exn fd) SHUTDOWN_SEND;
|
|
let+ result = Io.with_read i ~f:Io.Reader.to_string in
|
|
printfn "client: received %S" result;
|
|
Io.close o;
|
|
Io.close i
|
|
in
|
|
Fiber.fork_and_join_unit client server
|
|
in
|
|
Lev_fiber.run run |> Lev_fiber.Error.ok_exn;
|
|
[%expect
|
|
{|
|
|
server: starting
|
|
server: created
|
|
server: serving
|
|
client: starting
|
|
client: successfully connected
|
|
server: client connected
|
|
server: received "ping"
|
|
client: received "pong" |}]
|