Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8276903
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T08:31:28+00:00 2026-06-08T08:31:28+00:00

The usocket FAQ suggests that the way I should do this is by reading

  • 0

The usocket FAQ suggests that the way I should do this is by reading from a socket-stream and checking for an end-of-file result. That works in the case where I’ve got one thread active per socket, but it doesn’t seem to satisfy for the case where I’m trying to service multiple sockets in the same thread.

Consider something like

(defparameter *socket* (socket-listen "127.0.0.1" 123456))
(defparameter *client-connections*
   (list (socket-accept *socket*)
         (socket-accept *socket*)
         (socket-accept *socket*)
         (socket-accept *socket*)))

For this exercise, assume that I’ve actually got four clients connecting there. It seems like the way to go about serving them from one thread is something like

(wait-for-input *client-connections*)
(loop for sock in *client-connections*
      for stream = (socket-stream sock)
      when (listen stream)
        do (let ((line (read-line stream nil :eof)))
              (if (eq line :eof)
                  (progn (delete sock *client-connections*)
                         (socket-close sock))
                  (handle sock line))))

Except that this won’t work, because a disconnected socket still returns nil to listen, and an attempt to read from an active socket with no messages will block but wait-for-intput returns immediately when there’s a closed socket in the mix, even when no other socket has a message ready (though it seems to fail to specify which sockets caused it to return).

In the situation where no client has spoken in a little while, and third client disconnects, there doesn’t seem to be a good way of finding that out and closing that specific socket connection. I’d have to read them in sequence, except that since read blocks on no input, that would cause the thread to wait until the first two clients both sent a message.

The solutions I’ve got in mind, but haven’t found after some determined googling, are (in descending order of preference):

  1. A function otherwise equivalent to listen that returns t if a read on the targets’ stream would return an end-of-file marker. (Replacing listen above with this notional function would let the rest of it work as written)
  2. A function otherwise equivalent to wait-for-input that returns a list of closed sockets that cause it to trip. (In this case, I could iterate through the list of closed sockets, check that they’re actually closed with the suggested read technique, and close/pop them as needed)
  3. A function otherwise equivalent to wait-for-input that returns the first closed socket that caused it to trip. (As #2, but slower, because it prunes at most one inactive connection per iteration)
  4. Keeping track of how long its been since I’ve received input from each socket connection, and closing them out regardless after a certain period of inactivity. (Which I’d probably want to do anyway, but doing just this would potentially keep a bunch of dead connections around much longer than necessary)
  5. A function that attempts to read-char from a stream with an instant timeout, returns t if it encounters an :eof, and unread-chars anything else (returning nil after either timing out or unreading). (Which is a last resort since it seems like it would be trivially easy to break in a non-obvious-but-lethal way).

Also, if I’m thinking about this in precisely the wrong way, point that out too.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T08:31:30+00:00Added an answer on June 8, 2026 at 8:31 am

    It turns out that the thing I mention as Option 2 above exists.

    wait-for-input defaults to returning the full list of tracked connections for memory management purposes (someone was reportedly very concerned about consing new lists for the result), but it has a &key parameter that tells it to just return the connections that have something to say.

    (wait-for-input (list conn1 conn2 conn3 conn4) :ready-only t)
    

    is what I was looking for there. This returns all the ready connections, not just ones that are going to signal end-of-file, so the loop still needs to handle both cases. Something like

    (loop for sock in (wait-for-input *client-connections* :ready-only t)
          for stream = (socket-stream sock)
          do (let ((line (read-line stream nil :eof)))
                (if (eq line :eof)
                    (progn (delete sock *client-connections*)
                           (socket-close sock))
                    (handle sock line))))
    

    should do nicely.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

When I was reading from a usocket stream using the code below: (let ((stream
I'm writing web application where I need to push data from server to the
The HTTP library Drakma on CLISP generates an error USOCKET:UNSUPPORTED due to a bug

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.