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