Socket structure
signature SOCKET  (* OPTIONAL *)
structure Socket :> SOCKET  (* OPTIONAL *)
This structure provides the standard socket types, socket management, and I/O operations. The creation of sockets is relegated to domain-specific structures (such as INetSock and UnixSock). 
type ('af,'sock_type) sock
type 'af sock_addr
type dgram
type 'mode stream
type passive
type active
structure AF : sig
    type addr_family = NetHostDB.addr_family
    val list : unit -> (string * addr_family) list
    val toString   : addr_family -> string
    val fromString : string -> addr_family option
  end
structure SOCK : sig
    eqtype sock_type
    val stream : sock_type
    val dgram : sock_type
    val list : unit -> (string * sock_type) list
    val toString   : sock_type -> string
    val fromString : string -> sock_type option
  end
structure Ctl : sig
    val getDEBUG : ('af, 'sock_type) sock -> bool
    val setDEBUG : ('af, 'sock_type) sock * bool -> unit
    val getREUSEADDR : ('af, 'sock_type) sock -> bool
    val setREUSEADDR : ('af, 'sock_type) sock * bool
                         -> unit
    val getKEEPALIVE : ('af, 'sock_type) sock -> bool
    val setKEEPALIVE : ('af, 'sock_type) sock * bool
                         -> unit
    val getDONTROUTE : ('af, 'sock_type) sock -> bool
    val setDONTROUTE : ('af, 'sock_type) sock * bool
                         -> unit
    val getLINGER : ('af, 'sock_type) sock
                      -> Time.time option
    val setLINGER : ('af, 'sock_type) sock
                      * Time.time option -> unit
    val getBROADCAST : ('af, 'sock_type) sock -> bool
    val setBROADCAST : ('af, 'sock_type) sock * bool
                         -> unit
    val getOOBINLINE : ('af, 'sock_type) sock -> bool
    val setOOBINLINE : ('af, 'sock_type) sock * bool
                         -> unit
    val getSNDBUF : ('af, 'sock_type) sock -> int
    val setSNDBUF : ('af, 'sock_type) sock * int -> unit
    val getRCVBUF : ('af, 'sock_type) sock -> int
    val setRCVBUF : ('af, 'sock_type) sock * int -> unit
    val getTYPE : ('af, 'sock_type) sock -> SOCK.sock_type
    val getERROR : ('af, 'sock_type) sock -> bool
    val getPeerName : ('af, 'sock_type) sock
                        -> 'af sock_addr
    val getSockName : ('af, 'sock_type) sock
                        -> 'af sock_addr
    val getNREAD : ('af, 'sock_type) sock -> int
    val getATMARK : ('af, active stream) sock -> bool
  end
val sameAddr : 'af sock_addr * 'af sock_addr -> bool
val familyOfAddr : 'af sock_addr -> AF.addr_family
val bind : ('af, 'sock_type) sock * 'af sock_addr -> unit
val listen : ('af, passive stream) sock * int -> unit
val accept : ('af, passive stream) sock
               -> ('af, active stream) sock * 'af sock_addr
val acceptNB : ('af, passive stream) sock
                 -> (('af, active stream) sock
                 * 'af sock_addr) option
val connect : ('af, 'sock_type) sock * 'af sock_addr
                -> unit
val connectNB : ('af, 'sock_type) sock * 'af sock_addr
                  -> bool
val close : ('af, 'sock_type) sock -> unit
datatype shutdown_mode
  = NO_RECVS
  | NO_SENDS
  | NO_RECVS_OR_SENDS
val shutdown : ('af, 'mode stream) sock * shutdown_mode
                 -> unit
type sock_desc
val sockDesc : ('af, 'sock_type) sock -> sock_desc
val sameDesc : sock_desc * sock_desc -> bool
val select : {
                 rds : sock_desc list,
                 wrs : sock_desc list,
                 exs : sock_desc list,
                 timeout : Time.time option
               }
               -> {
                 rds : sock_desc list,
                 wrs : sock_desc list,
                 exs : sock_desc list
               }
val ioDesc : ('af, 'sock_type) sock -> OS.IO.iodesc
type out_flags = {don't_route : bool, oob : bool}
type in_flags = {peek : bool, oob : bool}
val sendVec : ('af, active stream) sock
                * Word8VectorSlice.slice -> int
val sendArr : ('af, active stream) sock
                * Word8ArraySlice.slice -> int
val sendVec' : ('af, active stream) sock
                 * Word8VectorSlice.slice
                 * out_flags -> int
val sendArr' : ('af, active stream) sock
                 * Word8ArraySlice.slice
                 * out_flags -> int
val sendVecNB  : ('af, active stream) sock
                   * Word8VectorSlice.slice -> int option
val sendVecNB' : ('af, active stream) sock
                   * Word8VectorSlice.slice
                   * out_flags -> int option
val sendArrNB  : ('af, active stream) sock
                   * Word8ArraySlice.slice -> int option
val sendArrNB' : ('af, active stream) sock
                   * Word8ArraySlice.slice
                   * out_flags -> int option
val recvVec  : ('af, active stream) sock * int
                 -> Word8Vector.vector
val recvVec' : ('af, active stream) sock * int * in_flags
                 -> Word8Vector.vector
val recvArr  : ('af, active stream) sock
                 * Word8ArraySlice.slice -> int
val recvArr' : ('af, active stream) sock
                 * Word8ArraySlice.slice
                 * in_flags -> int
val recvVecNB  : ('af, active stream) sock * int
                   -> Word8Vector.vector option
val recvVecNB' : ('af, active stream) sock * int * in_flags
                   -> Word8Vector.vector option
val recvArrNB  : ('af, active stream) sock
                   * Word8ArraySlice.slice -> int option
val recvArrNB' : ('af, active stream) sock
                   * Word8ArraySlice.slice
                   * in_flags -> int option
val sendVecTo : ('af, dgram) sock
                  * 'af sock_addr
                  * Word8VectorSlice.slice -> unit
val sendArrTo : ('af, dgram) sock
                  * 'af sock_addr
                  * Word8ArraySlice.slice -> unit
val sendVecTo' : ('af, dgram) sock
                   * 'af sock_addr
                   * Word8VectorSlice.slice
                   * out_flags -> unit
val sendArrTo' : ('af, dgram) sock
                   * 'af sock_addr
                   * Word8ArraySlice.slice
                   * out_flags -> unit
val sendVecToNB  : ('af, dgram) sock
                     * 'af sock_addr
                     * Word8VectorSlice.slice -> bool
val sendVecToNB' : ('af, dgram) sock
                     * 'af sock_addr
                     * Word8VectorSlice.slice
                     * out_flags -> bool
val sendArrToNB  : ('af, dgram) sock
                     * 'af sock_addr
                     * Word8ArraySlice.slice -> bool
val sendArrToNB' : ('af, dgram) sock
                     * 'af sock_addr
                     * Word8ArraySlice.slice
                     * out_flags -> bool
val recvVecFrom  : ('af, dgram) sock * int
                     -> Word8Vector.vector
                     * 'sock_type sock_addr
val recvVecFrom' : ('af, dgram) sock * int * in_flags
                     -> Word8Vector.vector
                     * 'sock_type sock_addr
val recvArrFrom  : ('af, dgram) sock
                     * Word8ArraySlice.slice
                     -> int * 'af sock_addr
val recvArrFrom' : ('af, dgram) sock
                     * Word8ArraySlice.slice
                     * in_flags -> int * 'af sock_addr
val recvVecFromNB  : ('af, dgram) sock * int
                       -> (Word8Vector.vector
                       * 'sock_type sock_addr) option
val recvVecFromNB' : ('af, dgram) sock * int * in_flags
                       -> (Word8Vector.vector
                       * 'sock_type sock_addr) option
val recvArrFromNB  : ('af, dgram) sock
                       * Word8ArraySlice.slice
                       -> (int * 'af sock_addr) option
val recvArrFromNB' : ('af, dgram) sock
                       * Word8ArraySlice.slice
                       * in_flags
                       -> (int * 'af sock_addr) option
type ('af,'sock_type) sock
INetSock.inet or  UnixSock.unix).  The type parameter 'sock_type  is instantiated with the appropriate socket  type (dgram  or stream). 
type 'af sock_addr
INetSock.inet  or UnixSock.unix). 
type dgram
type 'mode stream
structure AF
AF substructure defines an abstract type that represents  the different network-address families. 
val list : unit -> (string * addr_family) list
(name,af)  where name is the  name of the address family, and af is the actual address family  value.  
 The names of the address families are taken from the  symbolic constants used in the C Socket API and stripping the  leading ``AF_.''  For example, the Unix-domain address family is named  "UNIX", the Internet-domain address family is named  "INET", and the Apple Talk address family is  named "APPLETALK". 
val toString : addr_family -> string
val fromString : string -> addr_family option
toString (INetSock.inetAF)  returns the string "INET".  fromString returns  NONE if no family  value corresponds to the given name.  
 If a pair (name,af) is in the list returned  by list, then it is the case that name  is equal to toString(af). 
structure SOCK
SOCK substructure provides an abstract type and operations  for the different types of sockets.  This type is used by the getTYPE function. 
eqtype sock_type
val stream : sock_type
val dgram : sock_type
val list : unit -> (string * sock_type) list
(name,sty) where  name is the name of the socket type,  and sty is the actual socket type value.  
 The list of possible socket type names includes  "STREAM" for stream sockets,  "DGRAM" for datagram sockets, and  "RAW" for raw sockets.  These names are formed by taking the symbolic constants from  the C API and removing the leading ``SOCK_.'' 
val toString : sock_type -> string
val fromString : string -> sock_type option
fromString returns NONE  if no socket type value corresponds to the name.  
 If a pair (name,sty) is in the list returned  by list, then it is the case that name  is equal to toString(sty). 
structure Ctl
Ctl substructure provides support for  manipulating the options associated with a socket.  These functions raise the SysErr  exception when the argument socket has been closed. 
val getDEBUG : ('af, 'sock_type) sock -> bool
val setDEBUG : ('af, 'sock_type) sock * bool -> unit
SO_DEBUG flag for the socket. This flag  enables or disables low-level debugging within the kernel. Enabled, it  allows the kernel to maintain a history of the recent packets that  have been received or sent.  
val getREUSEADDR : ('af, 'sock_type) sock -> bool
val setREUSEADDR : ('af, 'sock_type) sock * bool -> unit
SO_REUSEADDR flag for the socket. When  true, this flag instructs the system to allow  reuse of local socket addresses in bind  calls.  
val getKEEPALIVE : ('af, 'sock_type) sock -> bool
val setKEEPALIVE : ('af, 'sock_type) sock * bool -> unit
SO_KEEPALIVE flag for the socket. When  true, the system will generate periodic transmissions  on a connected socket, when no other data is being exchanged.  
val getDONTROUTE : ('af, 'sock_type) sock -> bool
val setDONTROUTE : ('af, 'sock_type) sock * bool -> unit
SO_DONTROUTE flag for the socket. When  this flag is true, outgoing messages bypass the normal routing  mechanisms of the underlying protocol, and are instead directed to the  appropriate network interface as specified by the network portion of  the destination address. Note that this option can be specified on a  per message basis by using one of the  sendVec',  sendArr',  sendVecTo', or  sendArrTo'  functions.  
val getLINGER : ('af, 'sock_type) sock -> Time.time option
val setLINGER : ('af, 'sock_type) sock * Time.time option
                  -> unit
SO_LINGER flag for the  socket sock.  This flag controls the action taken when unsent messages are queued on  socket and a close is performed.  If the flag is set to NONE,  then the system will close the socket as quickly as possible, discarding  data if necessary.  If the flag is set to  SOME(t) and  the socket promises reliable delivery, then the system will block  the close operation until the  data is delivered or the timeout t expires.  If t is negative or too large, then the  Time is raised.  
val getBROADCAST : ('af, 'sock_type) sock -> bool
val setBROADCAST : ('af, 'sock_type) sock * bool -> unit
SO_BROADCAST flag for the socket sock, which  enables or disables the ability of the process to send broadcast  messages over the socket.  
val getOOBINLINE : ('af, 'sock_type) sock -> bool
val setOOBINLINE : ('af, 'sock_type) sock * bool -> unit
SO_OOBINLINE flag for the socket. When  set, this indicates that out-of-band data should be placed in the  normal input queue of the socket.  Note that this option can be specified on a  per message basis by using one of the  sendVec',  sendArr',  sendVecTo', or  sendArrTo'  functions.  
val getSNDBUF : ('af, 'sock_type) sock -> int
val setSNDBUF : ('af, 'sock_type) sock * int -> unit
val getRCVBUF : ('af, 'sock_type) sock -> int
val setRCVBUF : ('af, 'sock_type) sock * int -> unit
val getTYPE : ('af, 'sock_type) sock -> SOCK.sock_type
val getERROR : ('af, 'sock_type) sock -> bool
val getPeerName : ('af, 'sock_type) sock -> 'af sock_addr
val getSockName : ('af, 'sock_type) sock -> 'af sock_addr
val getNREAD : ('af, 'sock_type) sock -> int
val getATMARK : ('af, active stream) sock -> bool
val sameAddr : 'af sock_addr * 'af sock_addr -> bool
familyOfAddr addr 
bind (sock, sa) 
SysErr when the address  sa is already in use, when sock is already bound to  an address, or when sock has been closed. 
listen (sock, n) 
 This function raises the SysErr exception  if sock has been closed. 
accept sock 
bind  and enabled for listening via listen.  If a connection is present, accept returns a pair  (s,sa) consisting of  a new active socket s with the same properties  as sock and the address sa of the  connecting entity.  If no pending connections are present on  the queue then accept blocks  until a connection is requested.  One can test for pending connection requests by using the  select function to test the socket for reading.  
 This function raises the SysErr exception  if sock has not been properly bound and enabled, or it  sock has been closed. 
val acceptNB : ('af, passive stream) sock
                 -> (('af, active stream) sock
                 * 'af sock_addr) option
accept operation.  If the operation can complete without blocking (i.e., there is  a pending connection), then this function returns  SOME(s,sa),  where s is a new active socket with the same properties  as sock and sa is the the address of the  connecting entity.  If there are no pending connections, then this function returns  NONE.  
 This function raises the SysErr exception  if sock has not been properly bound and enabled, or it  sock has been closed. 
connect (sock, sa) 
 This function raises the SysErr exception  when the address specified by sa is unreachable, when the  connection is refused or times out, when sock is already  connected, or when sock has been closed. 
val connectNB : ('af, 'sock_type) sock * 'af sock_addr
                  -> bool
connect.  If the connection can be established without blocking the caller  (which is typically true for datagram sockets, but not stream sockets),  then true is returned.  Otherwise, false is returned and the connection attempt is  started; one can test for the completion of the connection by testing  the socket for writing using the select function.  This function will raise SysErr if it  is called on a socket for which a previous connection attempt has  not yet been completed. 
close sock 
SysErr  exception if the socket has already been closed.     
shutdown (sock, mode) 
NO_RECVS,  further receives will be disallowed.  If mode is NO_SENDS,  further sends will be disallowed.  If mode is NO_RECVS_OR_SENDS,  further sends and receives will be disallowed.  This function raises the SysErr  exception if the socket is not connected or has been closed. 
type sock_desc
sockDesc sock  
sameDesc (sd1, sd2)  
true if the two socket descriptors sd1  and sd2 describe the same underlying socket.  Thus, the expression  sameDesc(sockDesc sock, sockDesc sock)  will always return true for any socket sock. 
select {rds, wrs, exs, timeout}  
NONE never expires).  The result of select is a record of three lists of  socket descriptors containing the ready sockets from the corresponding argument lists.  The order in which socket descriptors appear in the argument lists is preserved in the  result lists.  A timeout is signified by a result of three empty lists.  
 This function raises SysErr if any of the  argument sockets have been closed or if the timeout value is negative.  
 Note that one can test if a call to accept will block  by using select to see if the socket is ready to read. Similarly, one can use select to test if a call to connect will block by seeing if the socket is ready to write. 
ioDesc sock 
pollDesc and poll in the  OS.IO structure.  Using the polling mechanism from OS.IO has  the advantage that different kinds of I/O objects can be mixed, but not  all systems support polling on sockets this way.  If an application is only polling sockets, then it is more portable to use  the select function defined above. 
type out_flags = {don't_route : bool, oob : bool}
type in_flags = {peek : bool, oob : bool}
sendVec (sock, slice) 
          sendArr (sock, slice) 
 These functions raise SysErr if sock has  been closed. 
sendVec' (sock, slice, {don't_route, oob}) 
          sendArr' (sock, slice, {don't_route, oob}) 
true,  the data is sent bypassing the normal routing mechanism of the protocol.  If oob is true, the data is  sent out-of-band, that is, before any other data which  may have been buffered.  
 These functions raise SysErr if sock has  been closed. 
val sendVecNB : ('af, active stream) sock
                  * Word8VectorSlice.slice -> int option
val sendVecNB' : ('af, active stream) sock
                   * Word8VectorSlice.slice
                   * out_flags -> int option
val sendArrNB : ('af, active stream) sock
                  * Word8ArraySlice.slice -> int option
val sendArrNB' : ('af, active stream) sock
                   * Word8ArraySlice.slice
                   * out_flags -> int option
sendVec,  sendVec',  sendArr, and  sendArr' (resp.).  They have the same semantics as their blocking forms, with the exception  that when the operation can complete without blocking, then the result  is wrapped in SOME and if the  operation would have to wait to send the data, then  NONE is returned instead. 
recvVec (sock, n) 
          recvVec'(sock, n, {peek,oob}) 
0), then the empty vector  will be returned.  
 In the second version, if peek is true, the data is received but not discarded from the connection. If oob is true, the data is received out-of-band,  that is, before any other incoming data that may have been buffered.  
 These functions raise SysErr if the  socket sock has been closed and  they raise Size if  n < 0 or  n > Word8Vector.maxLen. 
recvArr (sock, slice) 
          recvArr' (sock, slice, {peek, oob}) 
 For recvArr', if peek  is true, the data is received but not discarded from the  connection.  If oob is true, the data is received out-of-band,  that is, before any other incoming data that may have been buffered.  
 These functions raise SysErr if sock has  been closed. 
val recvVecNB : ('af, active stream) sock * int
                  -> Word8Vector.vector option
val recvVecNB' : ('af, active stream) sock * int * in_flags
                   -> Word8Vector.vector option
val recvArrNB : ('af, active stream) sock
                  * Word8ArraySlice.slice -> int option
val recvArrNB' : ('af, active stream) sock
                   * Word8ArraySlice.slice
                   * in_flags -> int option
recvVec,  recvVec',  recvArr, and  recvArr' (resp.).  They have the same semantics as their blocking forms, with the exception  that when the operation can complete without blocking, then the result  is wrapped in SOME and if the  operation would have to wait for input, then  NONE is returned instead. 
sendVecTo (sock, sa, slice) 
          sendArrTo (sock, sa, slice) 
 These functions raise SysErr if sock  has been closed or if the socket has been connected to a different  address than sa. 
sendVecTo' (sock, sa, slice, {don't_route, oob}) 
          sendArrTo' (sock, sa, slice, {don't_route, oob}) 
 If the don't_route flag is true, the data is sent  bypassing the normal routing mechanism of the protocol.  If oob is true, the data is sent  out-of-band, that is, before any other data which may have been buffered.  
 These functions raise SysErr if sock  has been closed or if the socket has been connected to a different  address than sa. 
val sendVecToNB : ('af, dgram) sock
                    * 'af sock_addr
                    * Word8VectorSlice.slice -> bool
val sendVecToNB' : ('af, dgram) sock
                     * 'af sock_addr
                     * Word8VectorSlice.slice
                     * out_flags -> bool
val sendArrToNB : ('af, dgram) sock
                    * 'af sock_addr
                    * Word8ArraySlice.slice -> bool
val sendArrToNB' : ('af, dgram) sock
                     * 'af sock_addr
                     * Word8ArraySlice.slice
                     * out_flags -> bool
sendVecTo,  sendVecTo',  sendArrTo, and  sendArrTo' (resp.).  They have the same semantics as their blocking forms, with the exception  that if the operation can complete without blocking, then the operation is  performed and true is returned.  Otherwise, false is returned and the message is not sent. 
recvVecFrom (sock, n) 
          recvVecFrom' (sock, n, {peek, oob}) 
(vec,sa), where the vector  vec is the received message, and sa is the  socket address from the which the data originated.  If the message is larger than n, then data may be lost.  
 In the second form, if peek is true, the data is  received but not discarded from the connection.  If oob is true, the data is received out-of-band,  that is, before any other incoming data that may have been buffered.  
 These functions raise SysErr if sock has  been closed; they raise Size if  n < 0 or  n > Word8Vector.maxLen. 
recvArrFrom (sock, slice) 
          recvArrFrom' (sock, slice) 
 For recvArrFrom', if peek  is true, the data is received but not discarded from the  connection. If oob is true, the data is  received out-of-band,  that is, before any other incoming data that may have been buffered.  
 These functions raise SysErr if sock has  been closed. 
val recvVecFromNB : ('af, dgram) sock * int
                      -> (Word8Vector.vector
                      * 'sock_type sock_addr) option
val recvVecFromNB' : ('af, dgram) sock * int * in_flags
                       -> (Word8Vector.vector
                       * 'sock_type sock_addr) option
val recvArrFromNB : ('af, dgram) sock
                      * Word8ArraySlice.slice
                      -> (int * 'af sock_addr) option
val recvArrFromNB' : ('af, dgram) sock
                       * Word8ArraySlice.slice
                       * in_flags
                       -> (int * 'af sock_addr) option
recvVecFrom,  recvVecFrom',  recvArrFrom, and  recvArrFrom' (resp.).  They have the same semantics as their blocking forms, with the exception  that when the operation can complete without blocking, then the result  is wrapped in SOME and if the  operation would have to wait for input, then  NONE is returned instead. 
GenericSock,INetSock,NetHostDB,NetServDB,UnixSock
Implementation note:
On Unix systems, the non-blocking mode of socket operations is controlled by changing the socket's state using the
setsockopt()system call. Thus, implementing the non-blocking operations in theSocketstructure may require tracking the socket's blocking/nonblocking state in the representation of thesocktype.
Generated October 02, 2003
Last Modified June 5, 1998
Comments to John Reppy.
This document may be distributed freely over the internet as long as the copyright notice and license terms below are prominently displayed within every machine-readable copy.
| 
 Copyright © 2003 AT&T and Lucent Technologies. All rights reserved. 
Permission is granted for internet users to make one paper copy for their
own personal use.  Further hardcopy reproduction is strictly prohibited. 
Permission to distribute the HTML document electronically on any medium
other than the internet must be requested from the copyright holders by
contacting the editors.
Printed versions of the SML Basis Manual are available from Cambridge
University Press.
To order, please visit
www.cup.org (North America) or
www.cup.cam.ac.uk (outside North America).  |