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