"unbind" a socket...?

Discussion of Common Lisp
Post Reply
infrared
Posts: 1
Joined: Thu Jan 02, 2014 12:54 pm

"unbind" a socket...?

Post by infrared » Thu Jan 02, 2014 1:04 pm

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?)

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: "unbind" a socket...?

Post by nuntius » Thu Jan 02, 2014 1:21 pm

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

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: "unbind" a socket...?

Post by pjstirling » Thu Jan 02, 2014 7:35 pm

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.

Post Reply