"unbind" a socket...?

Discussion of Common Lisp

"unbind" a socket...?

Postby 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?)
infrared
 
Posts: 1
Joined: Thu Jan 02, 2014 12:54 pm

Re: "unbind" a socket...?

Postby 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
User avatar
nuntius
 
Posts: 498
Joined: Sat Aug 09, 2008 10:44 am
Location: Burlington, MA

Re: "unbind" a socket...?

Postby 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.
pjstirling
 
Posts: 79
Joined: Sun Nov 28, 2010 4:21 pm


Return to Common Lisp

Who is online

Users browsing this forum: Google [Bot] and 4 guests

cron