Re: non-blocking READ-SEQUENCE
ngo@cartan.de (=?iso-8859-1?q?Nils_G=F6sche?=) schrieb am 09.12.03 23:29:43: > > "Jochen Schmidt" <jsc@dataheaven.de> writes: > > > When developing efficient I/O over sockets one could think that > > READ-SEQUENCE would be the right thing to transfer larger chunks at > > a whole. > > Quite so. > > > A problem that arises is that READ-SEQUENCE blocks if the peer does > > not send enought elements to fill the whole (bounded) sequence. > > > > What one would want is some kind of READ-SEQUENCE which blocks on > > the first element and after that fills the sequence as long as data > > is available on the socket. (semantically calling READ-CHAR-NO-HANG > > until it returns NIL). > > It seems to me that you really want a message based network protocol > and not a network stream. You could put a layer above your TCP stream > by adding a header with a length. Then do a READ-SEQUENCE for the > header, and another READ-SEQUENCE for the rest of the message. If I would design a network protocol I may do it like this - yes. Actually I'm implementing existing protocols which do not meet this criteria. I've hacked together a function which, with enough internal voodoo, seems to do what I want: (defun read-string-non-blocking (string stream &key (start 0) (end (length string))) ;; Block on the first character (let ((first-char (read-char stream))) (setf (char string start) first-char) (incf start)) ;; Copy the rest of the input-buffer ;; into the string (stream::with-stream-input-buffer (buffer index limit) stream (replace string buffer :start1 start :end1 end :start2 index :end2 limit) (let ((n (min (- limit index) (- end start)))) (incf start n) (incf index n))) ;; non-blocking refill of input-buffer by setting ;; read-timeout to zero (loop while (and (< start end) (without-interrupts (let ((timeout (stream:stream-read-timeout stream))) (unwind-protect (progn (setf (stream:stream-read-timeout stream) 0) (stream::stream-fill-buffer stream)) ;; Restore former timeout value (setf (stream:stream-read-timeout stream) timeout))))) do (stream::with-stream-input-buffer (buffer index limit) stream (replace string buffer :start1 start :end1 end :start2 index :end2 limit) (incf start (- limit index)) (setf index limit))) start) Perhaps this whole idea is just crap and the implementation bug-ridden and ugly - but I thought it could bring in some new ideas to the topic. ciao, Jochen ______________________________________________________________________________ WEB.DE FreeMail wird 5 Jahre jung! Feiern Sie mit uns und nutzen Sie die neuen Funktionen http://f.web.de/features/?mc=021130