A socket handle.
One of
:input
,
:output
, or
:io
.
An element type.
A positive number or
nil
.
The
socket-stream
class implements a buffered stream connected to a socket. The socket handle, specified by
:socket
, and the direction, specified by
:direction
, must be passed for a meaningful stream to be constructed. Common Lisp input functions such as
read-char
will see
end-of-file
if the other end of the socket is closed.
The
:element-type
keyword determines the expected element type of the stream traffic. However, stream input and output functions for character and binary data all work in the obvious way on a
socket-stream
with
element-type
base-char
,
(unsigned-byte 8)
or
(signed-byte 8)
. For example,
read-sequence
can be called with a string buffer and a binary
socket-stream
: the character data is constructed from the input as if by
code-char
. Similarly
write-sequence
can be called with a string buffer and a binary
socket-stream
: the output is converted from the character data as if by
char-code
. All standard stream I/O functions have this flexibility. Also, 8-bit binary data can be read and written to a
base-char
socket-stream
.
The
:read-timeout
initarg specifies the read-timeout in seconds, or is
nil
, meaning there are no timeouts during reads (this is the default).
The
read-timeout
property is intended for use when a socket connection might hang during a call to any Common Lisp input function. The
read-timeout
can be set by make-instance or by open-tcp-stream. It can also be modified by
(setf stream:stream-read-timeout)
. When
read-timeout
is
nil
, there is no timeout during reads and the call may hang. When
read-timeout
is not
nil
, and there is no input from the socket for more than
read-timeout
seconds, any reading function returns
end-of-file
. The
read-timeout
does not limit the time inside
read
, but the time between successful extractions of data from the socket. Therefore, if the reading needs several rounds it may take longer than
read-timeout
.
Using
(setf stream:stream-read-timeout)
on the stream while it is inside a read function has undefined effects. However, the setf function can be used between calls to read functions. The
read-timeout
property of a stream can be read by
(stream:stream-read-timeout stream)
The following makes a bidirectional stream connected to a socket specified by handle .
(make-instance 'comm:socket-stream
:socket handle
:direction :io
:element-type 'base-char)
This example creates a socket stream with a read-timeout:
(make-instance 'comm:socket-stream
:handle
handle
:direction :input
:read-timeout 42)
The following form illustrates character I/O in a binary
socket-stream
:
(with-open-stream (x
(comm:open-tcp-stream
"localhost" 80
:element-type '(unsigned-byte 8)))
(write-sequence (format nil "GET / HTTP/1.0~%~%") x)
(force-output x)
(let ((res (make-array 20 :element-type 'base-char)))
(values (read-sequence res x) res)))
The following form illustrates binary I/O in a
base-char
socket-stream
:
(with-open-stream (x
(comm:open-tcp-stream
"localhost" 80
:element-type 'base-char))
(write-sequence
(map '(simple-array (unsigned-byte 8) 1)
'char-code
(format nil "GET / HTTP/1.0~%~%"))
x)
(force-output x)
(let ((res (make-array 20
:element-type
'(unsigned-byte 8))))
(values (read-sequence res x)
(map 'string 'code-char res))))