author | blanchet |
Fri, 20 Dec 2013 20:36:38 +0100 | |
changeset 54838 | 16511f84913c |
parent 54342 | fbcaa9f08879 |
child 62354 | fdd6989cc8a0 |
permissions | -rw-r--r-- |
50800
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
1 |
(* Title: Pure/General/socket_io.ML |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
2 |
Author: Timothy Bourke, NICTA |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
3 |
Author: Makarius |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
4 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
5 |
Stream IO over TCP sockets. Following example 10.2 in "The Standard |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
6 |
ML Basis Library" by Emden R. Gansner and John H. Reppy. |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
7 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
8 |
Note: BinIO requires Poly/ML 5.5.x to work reliably. |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
9 |
*) |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
10 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
11 |
signature SOCKET_IO = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
12 |
sig |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
13 |
val make_streams: Socket.active INetSock.stream_sock -> BinIO.instream * BinIO.outstream |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
14 |
val open_streams: string -> BinIO.instream * BinIO.outstream |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
15 |
end; |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
16 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
17 |
structure Socket_IO: SOCKET_IO = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
18 |
struct |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
19 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
20 |
fun make_streams socket = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
21 |
let |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
22 |
val (host, port) = INetSock.fromAddr (Socket.Ctl.getSockName socket); |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
23 |
val name = NetHostDB.toString host ^ ":" ^ string_of_int port; |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
24 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
25 |
val rd = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
26 |
BinPrimIO.RD { |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
27 |
name = name, |
54342
fbcaa9f08879
avoid non-portable int constant -- make SML/NJ happy;
wenzelm
parents:
54340
diff
changeset
|
28 |
chunkSize = io_buffer_size, |
50800
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
29 |
readVec = SOME (fn n => Socket.recvVec (socket, n)), |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
30 |
readArr = SOME (fn buffer => Socket.recvArr (socket, buffer)), |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
31 |
readVecNB = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
32 |
readArrNB = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
33 |
block = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
34 |
canInput = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
35 |
avail = fn () => NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
36 |
getPos = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
37 |
setPos = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
38 |
endPos = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
39 |
verifyPos = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
40 |
close = fn () => Socket.close socket, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
41 |
ioDesc = NONE |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
42 |
}; |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
43 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
44 |
val wr = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
45 |
BinPrimIO.WR { |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
46 |
name = name, |
54342
fbcaa9f08879
avoid non-portable int constant -- make SML/NJ happy;
wenzelm
parents:
54340
diff
changeset
|
47 |
chunkSize = io_buffer_size, |
50800
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
48 |
writeVec = SOME (fn buffer => Socket.sendVec (socket, buffer)), |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
49 |
writeArr = SOME (fn buffer => Socket.sendArr (socket, buffer)), |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
50 |
writeVecNB = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
51 |
writeArrNB = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
52 |
block = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
53 |
canOutput = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
54 |
getPos = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
55 |
setPos = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
56 |
endPos = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
57 |
verifyPos = NONE, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
58 |
close = fn () => Socket.close socket, |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
59 |
ioDesc = NONE |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
60 |
}; |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
61 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
62 |
val in_stream = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
63 |
BinIO.mkInstream |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
64 |
(BinIO.StreamIO.mkInstream (rd, Word8Vector.fromList [])); |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
65 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
66 |
val out_stream = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
67 |
BinIO.mkOutstream |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
68 |
(BinIO.StreamIO.mkOutstream (wr, IO.BLOCK_BUF)); |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
69 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
70 |
in (in_stream, out_stream) end; |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
71 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
72 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
73 |
fun open_streams socket_name = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
74 |
let |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
75 |
fun err () = error ("Bad socket name: " ^ quote socket_name); |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
76 |
val (host, port) = |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
77 |
(case space_explode ":" socket_name of |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
78 |
[h, p] => |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
79 |
(case NetHostDB.getByName h of SOME host => host | NONE => err (), |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
80 |
case Int.fromString p of SOME port => port | NONE => err ()) |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
81 |
| _ => err ()); |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
82 |
val socket: Socket.active INetSock.stream_sock = INetSock.TCP.socket (); |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
83 |
val _ = Socket.connect (socket, INetSock.toAddr (NetHostDB.addr host, port)); |
54340
18c621069bf8
prefer TCP_NODELAY -- avoid extra buffering due to Nagle's algorithm;
wenzelm
parents:
54339
diff
changeset
|
84 |
val _ = INetSock.TCP.setNODELAY (socket, true); |
50800
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
85 |
in make_streams socket end; |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
86 |
|
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
87 |
end; |
c0fb2839d1a9
recovered buffered sockets from 11f622794ad6 -- requires Poly/ML 5.5.x;
wenzelm
parents:
diff
changeset
|
88 |