[usocket-devel] How to tell size of data waiting in a TCP socket?

Elliott Slaughter elliottslaughter at gmail.com
Sun May 1 03:44:27 UTC 2011


I have another minimal testcase. It actually doesn't exhibit a freeze like I
see in my application, but it's definitely not working, so I think it's
worth looking at.

The code:

(defun receive-each (connections)
  (let ((ready (usocket:wait-for-input connections :timeout 0 :ready-only
t)))
    (loop for connection in ready
       collect (read-line (usocket:socket-stream connection)))))

(defun receive-all (connections)
  (loop for messages = (receive-each connections)
     then (receive-each connections)
     while messages append messages))

(defun send (connection message)
  (format (usocket:socket-stream connection) "~a~%" message)
  (force-output (usocket:socket-stream connection)))

(defun server ()
  (let* ((listen (usocket:socket-listen usocket:*wildcard-host* 12345))
         (connection (usocket:socket-accept listen)))
    (loop for messages = (receive-all connection) then (receive-all
connection)
       do (format t "Got messages:~%~s~%" messages)
       do (sleep 1/50))))

(defun client ()
  (let ((connection (usocket:socket-connect "localhost" 12345)))
    (loop for i from 0
       do (send connection (format nil "This is message ~a." i))
       do (sleep 1/100))))

Here is what the output looks like on everything I've tested except SBCL on
Windows. (Tested on SBCL on Mac, and Clozure CL on Windows.)

* (server)
Got messages:
("This is message 0." "This is message 1." "This is message 2.")
Got messages:
("This is message 3." "This is message 4.")
...

Here is the output on SBCL on Windows.

* (server)
Got messages:
NIL
Got messages:
NIL
...

I think in this case wait-for-input never returns anything as ready so I
never read from the socket.

On Sat, Apr 30, 2011 at 1:13 AM, Elliott Slaughter <
elliottslaughter at gmail.com> wrote:

> Hi,
>
> I'm wondering if there is a good way to figure out how much data is
> available on a socket. Right now I have a situation where my program accepts
> messages over a TCP socket. To check to see if a single message is
> available, I can just call wait-for-input with :timeout 0. But in order to
> check for multiple messages on a single socket, I need multiple calls to
> wait-for-input. So something like
>
> (iter (for ready next (wait-for-input socket :timeout 0))
>       (while (read-message socket)))
>
> I'm avoiding multithreading to preserve compatibility with Lisps that don't
> support (or have unstable support for) threads.
>
> The above works on most implementations, but breaks on SBCL/Windows, where
> subsequent calls to wait-for-input appear to block, despite the :timeout 0
> parameter.
>
> There may very well be a bug in the SBCL/Windows implementation in usocket
> to chase down here. Alternatively, is there a better way to do the above
> (assuming that multithread is unavailable in the implementation I want to
> run this on)?
>
> Thanks.
>
> --
> Elliott Slaughter
>
> "Don't worry about what anybody else is going to do. The best way to
> predict the future is to invent it." - Alan Kay
>



-- 
Elliott Slaughter

"Don't worry about what anybody else is going to do. The best way to predict
the future is to invent it." - Alan Kay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/usocket-devel/attachments/20110430/042e8c0d/attachment.html>


More information about the usocket-devel mailing list