| author | blanchet | 
| Mon, 08 Sep 2014 15:54:33 +0200 | |
| changeset 58229 | cece11f6262a | 
| 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: 
54340diff
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: 
54340diff
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: 
54339diff
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 |