Previous: Internet Addresses and Socket Names, Up: Sockets [Contents][Index]
When a port is returned from one of these calls it is unbuffered. This allows both reading and writing to the same port to work. If you want buffered ports you can (assuming sock-port is a socket i/o port):
(require 'i/o-extensions) (define i-port (duplicate-port sock-port "r")) (define o-port (duplicate-port sock-port "w"))
Returns a SOCK_STREAM
socket of type family using
protocol. If family has the value AF_INET
,
SO_REUSEADDR
will be set. The integer argument protocol
corresponds to the integer protocol numbers returned (as vector
elements) from (getproto)
. If the protocol argument is not
supplied, the default (0) for the specified family is used. SCM
sockets look like ports opened for neither reading nor writing.
Returns a pair (cons) of connected SOCK_STREAM
(socket) ports of
type family using protocol. Many systems support only
socketpairs of the af-unix
family. The integer argument
protocol corresponds to the integer protocol numbers returned (as
vector elements) from (getproto). If the protocol argument is
not supplied, the default (0) for the specified family is used.
Makes socket no longer respond to some or all operations depending on the integer argument how:
Socket:shutdown
returns socket if successful, #f
if
not.
Returns socket (changed to a read/write port) connected to the
Internet socket on host host-number, port port-number or
the Unix socket specified by pathname. Returns #f
if not
successful.
Returns inet-socket bound to the integer port-number or the
unix-socket bound to new socket in the file system at location
pathname. Returns #f
if not successful. Binding a
unix-socket creates a socket in the file system that must be
deleted by the caller when it is no longer needed (using
delete-file
).
The bound (see bind) socket is readied to
accept connections. The positive integer backlog specifies how
many pending connections will be allowed before further connection
requests are refused. Returns socket (changed to a read-only
port) if successful, #f
if not.
The input port returned by a successful call to socket:listen
can
be polled for connections by char-ready?
(see char-ready?). This avoids blocking on
connections by socket:accept
.
Accepts a connection on a bound, listening socket. Returns an input/output port for the connection.
The following example is not too complicated, yet shows the use of sockets for multiple connections without input blocking.
;;;; Scheme chat server ;;; This program implements a simple `chat' server which accepts ;;; connections from multiple clients, and sends to all clients any ;;; characters received from any client. ;;; To connect to chat `telnet localhost 8001' (require 'socket) (require 'i/o-extensions) (let ((listener-socket (socket:bind (make-stream-socket af_inet) 8001)) (connections '())) (socket:listen listener-socket 5) (do () (#f) (let ((actives (or (apply wait-for-input 5 listener-socket connections) '()))) (cond ((null? actives)) ((memq listener-socket actives) (set! actives (cdr (memq listener-socket actives))) (let ((con (socket:accept listener-socket))) (display "accepting connection from ") (display (getpeername con)) (newline) (set! connections (cons con connections)) (display "connected" con) (newline con)))) (set! connections (let next ((con-list connections)) (cond ((null? con-list) '()) (else (let ((con (car con-list))) (cond ((memq con actives) (let ((c (read-char con))) (cond ((eof-object? c) (display "closing connection from ") (display (getpeername con)) (newline) (close-port con) (next (cdr con-list))) (else (for-each (lambda (con) (file-position con 0) (write-char c con) (file-position con 0)) connections) (cons con (next (cdr con-list))))))) (else (cons con (next (cdr con-list)))))))))))))
You can use ‘telnet localhost 8001’ to connect to the chat server, or you can use a client written in scheme:
;;;; Scheme chat client ;;; this program connects to socket 8001. It then sends all ;;; characters from current-input-port to the socket and sends all ;;; characters from the socket to current-output-port. (require 'socket) (require 'i/o-extensions) (define con (make-stream-socket af_inet)) (set! con (socket:connect con (inet:string->address "localhost") 8001)) (define (go) (define actives (wait-for-input (* 30 60) con (current-input-port))) (let ((cs (and actives (memq con actives) (read-char con))) (ct (and actives (memq (current-input-port) actives) (read-char)))) (cond ((or (eof-object? cs) (eof-object? ct)) (close-port con)) (else (cond (cs (display cs))) (cond (ct (file-position con 0) (display ct con) (file-position con 0))) (go))))) (cond (con (display "Connecting to ") (display (getpeername con)) (newline) (go)) (else (display "Server not listening on port 8001") (newline)))
Previous: Internet Addresses and Socket Names, Up: Sockets [Contents][Index]