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 theSocket
structure may require tracking the socket's blocking/nonblocking state in the representation of thesock
type.
Generated April 12, 2004
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 © 2004 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). |