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 |
|