src/Tools/WWW_Find/socket_util.ML
changeset 45066 11f622794ad6
child 51930 52fd62618631
equal deleted inserted replaced
45065:9a98c3bc72e4 45066:11f622794ad6
       
     1 (*  Title:      Tools/WWW_Find/socket_util.ML
       
     2     Author:     Timothy Bourke, NICTA
       
     3 
       
     4 Routines for working with sockets.  Following example 10.2 in "The
       
     5 Standard-ML Basis Library" by Emden R. Gansner and John H. Reppy.
       
     6 *)
       
     7 
       
     8 signature SOCKET_UTIL =
       
     9 sig
       
    10   val init_server_socket: string option -> int -> Socket.passive INetSock.stream_sock
       
    11   val make_streams: Socket.active INetSock.stream_sock -> BinIO.instream * BinIO.outstream
       
    12 end;
       
    13 
       
    14 structure Socket_Util: SOCKET_UTIL =
       
    15 struct
       
    16 
       
    17 fun init_server_socket opt_host port =
       
    18   let
       
    19     val sock = INetSock.TCP.socket ();
       
    20     val addr =
       
    21       (case opt_host of
       
    22          NONE => INetSock.any port
       
    23        | SOME host =>
       
    24            NetHostDB.getByName host
       
    25            |> the
       
    26            |> NetHostDB.addr
       
    27            |> rpair port
       
    28            |> INetSock.toAddr
       
    29            handle Option => raise Fail ("Cannot resolve hostname: " ^ host));
       
    30     val _ = Socket.bind (sock, addr);
       
    31     val _ = Socket.listen (sock, 5);
       
    32   in sock end;
       
    33 
       
    34 fun make_streams sock =
       
    35   let
       
    36     val (haddr, port) = INetSock.fromAddr (Socket.Ctl.getSockName sock);
       
    37 
       
    38     val sock_name =
       
    39       implode [ NetHostDB.toString haddr, ":", string_of_int port ];
       
    40 
       
    41     val rd =
       
    42       BinPrimIO.RD {
       
    43         name = sock_name,
       
    44         chunkSize = Socket.Ctl.getRCVBUF sock,
       
    45         readVec = SOME (fn sz => Socket.recvVec (sock, sz)),
       
    46         readArr = SOME (fn buffer => Socket.recvArr (sock, buffer)),
       
    47         readVecNB = NONE,
       
    48         readArrNB = NONE,
       
    49         block = NONE,
       
    50         canInput = NONE,
       
    51         avail = fn () => NONE,
       
    52         getPos = NONE,
       
    53         setPos = NONE,
       
    54         endPos = NONE,
       
    55         verifyPos = NONE,
       
    56         close = fn () => Socket.close sock,
       
    57         ioDesc = NONE
       
    58       };
       
    59 
       
    60     val wr =
       
    61       BinPrimIO.WR {
       
    62         name = sock_name,
       
    63         chunkSize = Socket.Ctl.getSNDBUF sock,
       
    64         writeVec = SOME (fn buffer => Socket.sendVec (sock, buffer)),
       
    65         writeArr = SOME (fn buffer => Socket.sendArr (sock, buffer)),
       
    66         writeVecNB = NONE,
       
    67         writeArrNB = NONE,
       
    68         block = NONE,
       
    69         canOutput = NONE,
       
    70         getPos = NONE,
       
    71         setPos = NONE,
       
    72         endPos = NONE,
       
    73         verifyPos = NONE,
       
    74         close = fn () => Socket.close sock,
       
    75         ioDesc = NONE
       
    76       };
       
    77 
       
    78     val in_strm =
       
    79       BinIO.mkInstream (
       
    80         BinIO.StreamIO.mkInstream (rd, Word8Vector.fromList []));
       
    81 
       
    82     val out_strm =
       
    83       BinIO.mkOutstream (
       
    84         BinIO.StreamIO.mkOutstream (wr, IO.BLOCK_BUF));
       
    85 
       
    86     in (in_strm, out_strm) end;
       
    87 
       
    88 end;
       
    89