This library package defines a number of predicates manipulating
sockets. They are all rather straight-forward interfaces to the
corresponding BSD-type socket functions with the same name (except
current_host/1
). The reader should therefore study the
appropriate documents for a deeper description.
The Domain is either the atom 'AF_INET'
or
'AF_UNIX'
. They correspond directly to the same domains in
BSD-type sockets. 'AF_UNIX'
may not be available on non-UNIX
platforms.
An Address is either 'AF_INET'(Host,Port)
or
'AF_UNIX'(SocketName)
. Host is an atom denoting a
hostname (not an IP-address), Port is a portnumber and
SocketName is an atom denoting a socket. A reader familiar
with BSD sockets will understand this immediately.
All streams below can be both read from and written on. All I/O
predicates operating on streams can be used, for example
read/2
, write/2
, format/3
, current_stream/3
,
etc. Socket streams are block buffered both on read and write by
default. This can be changed by calling socket_buffering/4
.
To load the package, enter the query
| ?- use_module(library(sockets)).
socket(
+Domain,
-Socket)
socket_close(
+Socket)
socket_connect/2
should
not be closed by socket_close/1
as they will be closed when the
corresponding stream is closed.
socket_bind(
+Socket, 'AF_UNIX'(
+SocketName))
socket_bind(
+Socket, 'AF_INET'(
?Host,
?Port))
socket_connect(
+Socket, 'AF_UNIX'(
+SocketName),
-Stream)
socket_connect(
+Socket, 'AF_INET'(
+Host,
+Port),
-Stream)
socket_listen(
+Socket,
+Length)
socket_accept(
+Socket,
-Stream)
socket_accept(
+Socket,
-Client,
-Stream)
'AF_INET'
domain, Client will be
unified with an atom containing the Internet host address of
the connecting entity in numbers-and-dots notation. For other domains,
Client will be unbound.
Under Windows socket_accept/[2,3]
is not interruptible. This will
prevent the process from terminating or responding to keyboard
interrupt. A workaround is to use socket_select/5
with a timeout,
something like:
%% same as socket_accept/3 but will be interruptible with CTRL-C, %% CTRL-BREAK etc (within 2 seconds) nonblocking_socket_accept(Socket, Client, Stream) :- Seconds = 2, % wait this long between retries MicroSeconds = 0, TimeOut = Seconds:MicroSeconds, repeat, % repeat until connection or error socket_select([accept-Socket], Accepted, TimeOut, [], _ReadStreams), %% Here Accepted == [] if the timeout period expired Accepted = [accept-connection(Client1, Stream1)], !, Client = Client1, Stream = Stream1.
socket_buffering(
+Stream,
+Direction,
-OldBuf,
+NewBuf)
read
or write
. OldBuf and
NewBuf should be unbuf
for unbuffered I/O or fullbuf
for block buffered I/O.
socket_select(
+TermsSockets,
-NewTermsStreams,
+TimeOut,
+Streams,
-ReadStreams)
socket_select
. Under UNIX, a stream can be any
stream associated with a file descriptor but
socket_select/5
may block for non-socket streams even
though there is data available. The reason is that non-socket
streams can have buffered data available, e.g. within a C
stdio
FILE*
.
socket_select/5
also waits for connections to the sockets
specified by TermsSockets. This argument should be a
list of Term-Socket pairs, where Term,
which can be any term, is used as an
identifier. NewTermsStreams is a list of
Term-connection(
Client,
Stream)
pairs,
where Stream is a new stream open for communicating with a
process connecting to the socket identified with Term,
Client is the client host address (see socket_accept/3
).
If TimeOut is instantiated to off
, the
predicate waits until something is available. If TimeOut is
S:U
the predicate waits at most S
seconds and
U
microseconds. Both S
and U
must be integers >=0.
If there is a timeout, ReadStreams and NewTermsStreams are
[]
.
socket_select(
+Sockets,
-NewStreams,
+TimeOut,
+Streams,
-ReadStreams)
socket_select(
+Socket,
-NewStream,
+TimeOut,
+Streams,
-ReadStreams)
socket_select(
+Sockets,
-NewStreams,
-NewClients,
+TimeOut,
+Streams,
-ReadStreams)
socket_select(
+Socket,
-NewStream,
-NewClient,
+TimeOut,
+Streams,
-ReadStreams)
socket_select/[5,6]
also wait for connections to the sockets in
the list Sockets. NewStreams is the list of new
streams opened for communicating with the connecting
processes. NewClients is the corresponding list of client
host addresses (see socket_accept/3
).
The second form requires one socket (not a list) for the first
argument and returns a stream, NewStream, if a
connection is made.
current_host(
?HostName)
hostname_address(
+HostName,
-HostAddress)
hostname_address(
-HostName,
+HostAddress)