[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
6.7.4 Socket support
Bigloo defines sockets, on systems that support them, as first class objects. Sockets permits processes to communicate even if they are on different machines. Sockets are useful for creating client-server applications. The implementation and this documentation are, to a great extent copies of the STk [Gallesio95] socket support.
Bigloo supports both stream-oriented sockets and datagram sockets (see (libc)The GNU C Library Reference Manual). Stream-oriented sockets are created and manipulated with the following procedures.
- bigloo procedure: make-client-socket hostname port-number #!key (timeout 0) (inbuf #t) (outbuf #t) (domain 'inet)
-
make-client-socket
returns a new socket object. This socket establishes a link between the running application listening on port port-number of hostname. If keyword arguments inbuf and outbuf describe the buffer to be used. Each can either be:- A positive fixnum, this gives the size of the buffer.
- The boolean
#t
, a buffer is allocated by the Bigloo runtime system with a default size. - The boolean
#f
, the socket is unbufferized. - A string, it is used as buffer.
Unbuffered sockets are useful for socket clients connected to servers that do not emit #\Newline character after emissions. If the optional argument timeout is missing or is
0
, the execution blocks until the connection is established. If the timeout is provided, the execution unblocks after timeout microseconds unless the connection is established.The domain argument specifies the protocol used by the socket. The supported domains are:
-
inet
: IPv4 Internet protocols. -
unix
: Unix sockets for local inter-process communications. -
local
: Same asunix
.
If the connection cannot be established, an
&io-error
is raised (see Errors, Assertions, and Traces).When a socket is used in unbufferized mode the characters available on the input port must be read exclusively with
read-char
orread-line
. It is forbidden to useread
or any regular grammar. This limitation is imposed by Rgc (see Regular parsing) that intrinsicly associates buffers with regular grammars. If the current Rgc implementation is improved on the coming version this restriction will be eliminated.Example:
;; open a client socket on port 80: (make-client-socket "www.inria.fr" 80) ;; open an unbufferized connection (make-client-socket "www.inria.fr" 80 :buffer #f)
- bigloo procedure: socket? obj
- bigloo procedure: socket-server? obj
- bigloo procedure: socket-client? obj
Returns
#t
if obj is a socket, a socket server a socket client. Otherwise returns#f
. Socket servers and socket clients are sockets.
- bigloo procedure: socket-hostname socket
Returns a string which contains the name of the distant host attached to socket. If socket has been created with
make-client-socket
this procedure returns the official name of the distant machine used for connection. If socket has been created withmake-server-socket
, this function returns the official name of the client connected to the socket. If no client has used yet the socket, this function returns#f
.
- bigloo procedure: socket-host-address socket
-
Returns a string which contains the IP number of the distant host attached to socket. If socket has been created with
make-client-socket
this procedure returns the IP number of the distant machine used for connection. If socket has been created withmake-server-socket
, this function returns the address of the client connected to the socket. If no client has used yet the socket, this function returns#f
.
- bigloo procedure: socket-local-address socket
-
Returns a string which contains the IP number of the local host attached to socket.
- bigloo procedure: socket-input socket
- bigloo procedure: socket-output socket
-
Returns the file port associated for reading or writing with the program connected with socket. If no connection has already been established, these functions return
#f
.The following example shows how to make a client socket. Here we create a socket on port 13 of the machine “
kaolin.unice.fr
”(1):(let ((s (make-client-socket "kaolin.unice.fr" 13))) (print "Time is: " (read-line (socket-input s))) (socket-shutdown s))
- bigloo procedure: make-server-socket #!optional (port 0) #!key (name #f) (backlog 5)
make-server-socket
returns a new socket object. The socket will be listening on the network interface name, either on the specified port, or on a port chosen by the system (usually the first port available on the network interface). The name can be an IP number as a string, or a host name, whose first IP address will be used (as returned by the name server lookup).The backlog argument specifies the size of the wait-queue used for accepting connections.
- bigloo procedure: socket-accept socket #!key (errp #t) (inbuf #t) (outbuf #t)
socket-accept
waits for a client connection on the given socket. It returns aclient-socket
. If no client is already waiting for a connection, this procedure blocks its caller; otherwise, the first connection request on the queue of pending connections is connected to socket. This procedure must be called on a server socket created withmake-server-socket
.The arguments inbuf and outbuf are similar to the ones used by
make-client-socket
. That is, each can either be:- A positive fixnum, this gives the size of the buffer.
- The boolean
#t
, a buffer is allocated. - The boolean
#f
, the socket is unbufferized. - A string, it is used as buffer.
The keyword argument errp is a boolean. The value
#t
means that if an error is raised it is signaled. Otherwise, it is omitted.Note: When a socket is used in unbufferized mode the characters available on the input port must be read exclusively with
read-char
orread-line
. It is forbidden to useread
or any regular grammar. This limitation is imposed by Rgc (see Regular parsing) that intrinsicly associate buffers with regular grammars. If the current Rgc implementation is improved on the coming version this restriction will be suppressed.The following exemple is a simple server which waits for a connection on the port 1234(2). Once the connection with the distant program is established, we read a line on the input port associated to the socket and we write the length of this line on its output port.
(let* ((s (make-server-socket 1234)) (s2 (socket-accept s))) (let ((l (read-line (socket-input s2)))) (fprint (socket-output s2) "Length is: " (string-length l)) (flush-output-port (socket-output s2))) (socket-close s2) (socket-shutdown s))
- bigloo procedure: socket-close socket
The function
socket-close
closes the connection established with asocket-client
.
- bigloo procedure: socket-shutdown socket #!optional (close #t)
Socket-shutdown
shutdowns the connection associated to socket. Close is a boolean; it indicates if the socket must be closed or not, when the connection is destroyed. Closing the socket forbids further connections on the same port with thesocket-accept
procedure. Omitting a value for close implies the closing of socket. The result ofsocket-shutdown
is undefined.
- bigloo procedure: socket-down? socket
Returns
#t
if socket has been previously closed withsocket-shutdown
. It returns#f
otherwise.
Here is another example of making use of stream sockets:
(define s1 (make-server-socket)) (define s2 #unspecified) (dynamic-wind ;; Init: Launch an xterm with telnet running ;; on the s listening port and connect (lambda () (run-process "/usr/X11R6/bin/xterm" "-display" ":0" "-e" "telnet" "localhost" (number->string (socket-port-number s1))) (set! s2 (socket-accept s1)) (display #"\nWelcome on the socket REPL.\n\n> " (socket-output s2)) (flush-output-port (socket-output s2))) ;; Action: A toplevel like loop (lambda () (let loop () (let ((obj (eval (read (socket-input s2))))) (fprint (socket-output s2) "; Result: " obj) (display "> " (socket-output s2)) (flush-output-port (socket-output s2)) (loop)))) ;; Termination: We go here when ;; -a: an error occurs ;; -b: connection is closed (lambda () (print #"Shutdown ......\n") (socket-close s2) (socket-shutdown s1)))
Here is a second example that uses sockets. It implements
a client-server architecture and it uses unbufferized
(see socket-accept
) input ports.
First, here is the code of the client:
(module client) (let* ((s (make-client-socket "localhost" 8080 #f)) (p (socket-output s))) (display "string" p) (newline p) (display "abc" p) (flush-output-port p) (let loop () (loop)))
Then, here is the code of the server:
(module server) (let* ((s (make-server-socket 8080)) (s2 (socket-accept s :inbuf #f))) (let ((pin (socket-input s2))) (let loop () (display (read-char pin)) (flush-output-port (current-output-port)) (loop))))
At, to conclude here the source code for a server waiting for multiple consecutive connections:
(define (main argv) (let ((n (if (pair? (cdr argv)) (string->integer (cadr argv)) 10)) (s (make-server-socket))) (print "s: " s) (let loop ((i 0)) (if (<fx i n) (let ((s2 (socket-accept s))) (print "i: " i " " s2) (print (read-line (socket-input s2))) (socket-close s2) (loop (+fx i 1))) (socket-shutdown s)))))
Bigloo also provides primitives dealing with datagram sockets, for use with transports such as UDP. These are shown below:
- bigloo procedure: make-datagram-server-socket port
Return a datagram server socket bound to the loopback address on port, and whose address family and protocol family are those normally used for services on port.
- bigloo procedure: make-datagram-unbound-socket [(domain 'inet)]
Return an unbound datagram socket. It may then be used in conjunction with
datagram-socket-send
anddatagram-socket-receive
, for instance send to and receive from a UDP multicast address.
- bigloo procedure: datagram-socket-receive sock size
Receive up to size bytes from datagram socket sock, and return them as a string.
- bigloo procedure: datagram-socket-send sock message host port
Send string message over datagram socket sock to host and port. host must be a string denoting an IPv4 or IPv6 address. On success, return the number of bytes actually sent.
- bigloo procedure: host hostname
- bigloo procedure: hostinfo hostname
-
Returns the IP number of hostname. When hostname is not found, the
io-unknown-host-error
exception is raided (see Errors, Assertions, and Traces).The function
hostinfo
possibly returns more information about the host. It returns an association list made out the information about the host. This list might contain aname
entry, anaddresses
entry, and aaliases
entry.Some back-ends (e.g., the C back-end) implements DNS caching. This may dramatically improve the performance of intensive networking applications. DNS caching can be control by the means of two parameters:
bigloo-dns-enable-cache
andbigloo-dns-cache-validity-timeout
(see Parameters).
- bigloo procedure: get-interfaces
Returns the list of configured interfaces, their associated IP addresses, their protocol, and, if supported by the system, the hardware address (the mac address).
- bigloo procedure: get-protocols
Reads all the entries from the protocols database and returns a list of protocol entries. Each entries consists in a list of three elements:
- a string denoting the protocol name,
- an integer denoting the protocol number,
- a list of strings denoting the protocol aliases.
- bigloo procedure: get-protocol number-or-name
Returns the protocol entry found in the protocols database. The argument number-of-name is either an integer or a string.
- bigloo procedure: socket-option socket option-name
- bigloo procedure: socket-option-set! socket option-name val
These two functions get and set socket option. The argument option-name must be a keyword. If the option-name is not supported by the Bigloo runtime system, the function
socket-option
returns the value#unspecified
otherwise, it returns the option value. If the option-name is not supported, the functionsocket-option-set!
returnsfalse
. Otherwise it returns a non false value.Here is a list of possibly supported option-name values:
-
:SO_KEEPALIVE
-
:SO_OOBINLINE
-
:SO_RCVBUF
-
:SO_SNDBUF
-
:SO_REUSEADDR
-
:SO_TIMEOUT
-
:SO_SNDTIMEO
-
:SO_RCVTIMEO
-
:TCP_CORK
-
:TCP_QUICKACK
-
:TCP_NODELAY
The
:SO_KEEPALIVE
option can be use to implement automatic notification of client disconnection. It requires system tuning for enabling TCP keeplive support. On Linux additional information may be found on the “TCP Keepalive HOWTO” (see http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/).-
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on March 31, 2014 using texi2html 5.0.