5. Bigloo -- Standard Library<br>5.9 Socket support

5. Bigloo -- Standard Library
5.9 Socket support

Browsing

Home: Bigloo
A ``practical Scheme compiler''
User manual for version 2.6b
December 2003

Previous chapter: Core Language
Next chapter: Pattern Matching

Standard Library

5.1 Scheme Library
  5.1.1 Booleans
  5.1.2 Equivalence predicates
  5.1.3 Pairs and lists
  5.1.4 Symbols
  5.1.5 Keywords
  5.1.6 Numbers
  5.1.7 Characters
  5.1.8 UCS-2 Characters
  5.1.9 Strings
  5.1.10 Unicode (UCS-2) Strings
  5.1.11 Vectors
  5.1.12 Control features
5.2 Input and output
5.3 Structures and Records
  5.3.1 Structures
  5.3.2 Records (SRFI-9)
5.4 Serialization
5.5 Bit manipulation
5.6 Hash Tables
  5.6.1 Hash tables
  5.6.2 Deprecated Hash tables
5.7 System programming
  5.7.1 Operating System interface
  5.7.2 Files
5.8 Process support
5.9 Socket support
5.10 Date
5.11 Posix Regular Expressions
  5.11.1 Regular Expressions Procedures
  5.11.2 Regular Expressions Pattern Language
  5.11.3 An Extended Example

Chapters

  Acknowledgements
1. Table of contents
2. Overview of Bigloo
3. Modules
4. Core Language
5. Standard Library
6. Pattern Matching
7. Object System
8. Threads
9. Regular parsing
10. Lalr(1) parsing
11. Errors and Assertions
12. Eval and code interpretation
13. Macro expansion
14. Command Line Parsing
15. Explicit typing
16. The C interface
17. The Java interface
18. Bigloo Libraries
19. Extending the Runtime System
20. SRFIs
21. DSSSL support
22. Compiler description
23. User Extensions
24. Bigloo Development Environment
25. Global Index
26. Library Index
  Bibliography

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.

make-client-socket hostname port-number [buffered]bigloo procedure
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 optional argument buffered is #f then the input port associated with the socket is unbuffered. This is useful for socket clients connected to servers that do not emit #\Newline character after emissions. If optional argument buffered is missing or is not to #f the input port uses a buffer.

When a socket is used in unbufferized mode the characters available on the input port must be read exclusively with read-char or read-line. It is forbidden to use read 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.

socket? objbigloo procedure
socket-server? objbigloo procedure
socket-client? objbigloo procedure
Returns #t if obj is a socket, a socket server a socket client. Otherwise returns #f. Socket servers and socket clients are sockets.

socket-hostname socketbigloo procedure
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 with make-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.

socket-host-address socketbigloo procedure
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 with make-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.

socket-local-address socketbigloo procedure
Returns a string which contains the IP number of the local host attached to socket.



socket-port-number socketbigloo procedure
Returns the integer number of the port used for socket.

socket-input socketbigloo procedure
socket-output socketbigloo procedure
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'' is generally used for testing: making a connection to it permits to know the distant system's idea of the time of day.1:
(let ((s (make-client-socket "kaolin.unice.fr" 13)))
  (print "Time is: " (read-line (socket-input s)))
  (socket-shutdown  s))

make-server-socket [port-number]bigloo procedure
make-server-socket returns a new socket object. If port-number is specified, the socket is listening on the specified port; otherwise, the communication port is choosen by the system.

socket-accept socket [buffered]bigloo procedure
The function socket-accept replaces the former Bigloo functions socket-accept-connection and socket-dup. socket-accept waits for a client connection on the given socket. It returns a client-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 with make-server-socket. If optional argument buffered is #f then the input port associated with the socket is unbuffered. This is useful for socket clients connected to servers that do not emit #\Newline character after emissions. If optional argument buffered is missing or is not to #f the input port uses a buffer. The result of socket-accept is undefined.

Note: When a socket is used in unbufferized mode the characters available on the input port must be read exclusively with read-char or read-line. It is forbidden to use read 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 listening socket with the telnet command. With the given example, this can be achived by typing the following command in a window shell: $ telnet localhost 12342. 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 s) "Length is: " (string-length l))
    (flush-output-port (socket-output s2)))
  (socket-close s)
  (socket-shutdown s))

socket-accept-connection socket [buffered]bigloo procedure
socket-accept-connection waits for a client connection on the given 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.

note:This function is part of the old Bigloo API. It was intended to be used in conjunction with socket-accept-connection. The new API made of socket-accept and socket-close should be preferred.

This procedure must be called on a server socket created with make-server-socket. If optional argument buffered is #f then the input port associated with the socket is unbuffered. This is useful for socket clients connected to servers that do not emit #\Newline character after emissions. If optional argument buffered is missing or is not to #f the input port uses a buffer. The result of socket-accept-connection is undefined.

Note: When a socket is used in unbufferized mode the characters available on the input port must be read exclusively with read-char or read-line. It is forbidden to use read 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 listening socket with the telnet command. With the given example, this can be achived by typing the following command in a window shell: $ telnet localhost 12343. 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)))
  (socket-accept-connection s)
  (let ((l (read-line (socket-input s))))
    (fprint (socket-output s) "Length is: " (string-length l))
    (flush-output-port (socket-output s)))
  (socket-shutdown s))

socket-close socketbigloo procedure
The function socket-close closes the connection established with a socket-client.

socket-shutdown socket [close]bigloo procedure
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 the socket-accept-connection procedure. Omitting a value for close implies the closing of socket. The result of socket-shutdown is undefined.

The following example shows a simple server: when there is a new connection on the port number 1234, the server displays the first line sent to it by the client, discards the others and go back waiting for further client connections.
(let ((s (make-server-socket 1234)))
  (let loop ()
    (socket-accept-connection s)
    (print "I've read: " (read-line (socket-input s)))
    (socket-shutdown s #f)
    (loop)))

socket-down? socketbigloo procedure
Returns #t if socket has been previously closed with socket-shutdown. It returns #f otherwise.

socket-dup socketbigloo procedure
Returns a copy of socket.

note:This function is part of the old Bigloo API. It was intended to be used in conjunction with socket-accept-connection. The new API made of socket-accept and socket-close should be preferred.

The original and the copy socket can be used interchangeably. However, if a new connection is accepted on one socket, the characters exchanged on this socket are not visible on the other socket. Duplicating a socket is useful when a server must accept multiple simultaneous connections. The following example creates a server listening on port 1234. This server is duplicated and, once two clients are present, a message is sent on both connections.
(define s1 (make-server-socket 1234))
(define s2 (socket-dup s1))
(socket-accept-connection s1)
(socket-accept-connection s2)
;; blocks until two clients are present
(display #"Hello,\n" (socket-output s1))
(display #"world\n"  (socket-output s2))
(flush-output-port (socket-output s1))
(flush-output-port (socket-output s2))

Here is another example of making use of 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 #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)))))



This Scribe page has been generated by scribeinfo.
Last update Wed Dec 17 01:52:08 2003