Page 1 of 1

"unbind" a socket...?

PostPosted: Thu Jan 02, 2014 1:04 pm
by infrared
Hi. I'm trying to learn beginning network programming. I wrote a little SBCL code to accept a connection and then close it:

Code: Select all
(defun serve (port)
  (let ((sock (make-instance 'inet-socket :type :stream :protocol :tcp)))
    (progn
      (socket-bind sock (make-inet-address "127.0.0.1") port)
      (socket-listen sock 100)
      (let ((connection (socket-accept sock)))
   (socket-close connection)))))


It works, in that if I run (serve 5555) I can then use a telnet client to connect to localhost:5555 (which disconnects immediately). However, if afterwards I try to run the serve function again with the same port number, I get the error "<SB-BSD-SOCKETS:ADDRESS-IN-USE-ERROR>". If I change the port number, it will work once with that port, and then get the aforementioned error always after that.

I get the same problem trying to code something using usocket, which suggests a fundamental misunderstanding on my part. Is there a cleanup step I'm missing? (Like, "unbinding" the socket somehow?)

Re: "unbind" a socket...?

PostPosted: Thu Jan 02, 2014 1:21 pm
by nuntius
Welcome to the fun of network sockets. There are a few options for this. Keep the socket around for multiple connections (generally preferred), set SO_REUSEADDR, or close the socket after the connection. Regardless of your primary strategy, I almost always set SO_REUSEADDR so an abnormal exit doesn't hang the port until a kernel timeout.

"The" guide is the Stevens book.
http://www.amazon.com/Unix-Network-Prog ... 131411551/

Beej's guide is pretty good too.
http://beej.us/guide/bgnet/output/html/ ... .html#bind
http://beej.us/guide/bgnet/output/html/ ... #closedown

Re: "unbind" a socket...?

PostPosted: Thu Jan 02, 2014 7:35 pm
by pjstirling
It's also worth pointing out that while those guides are written aiming at C (where you can't), as a user of an interactive language you can redefine functions at run time, so the "right" way is to define a bind-accept loop that dispatches to the "real" function that does the guts of your per-connection processing. With a model like this you only need to redefine the second function, and so you don't need to keep opening new sockets.

OTOH if you are really set on handling one connection, and one connection only, you will need to properly close both the accept and bind sockets as per above.