Jay Taylor's notes
back to listing indexThe port 0 trick | David North
[web search]The port 0 trick
The port 0 trick came in handy when writing eximunit, and it’s something surprisingly few developers know about, so I thought it worth recounting here:
The problem: you want to set up a web/mail/whatever server programmatically (e.g. as part of some tests). This server wants to bind to port 80/25/whatever. Your first problem is that it can’t bind to these because you’re not running your tests as root (or as an administrator on Windows).
The lazy approach at this point is to hard-code a port number over 1024, which you don’t have to be privileged to bind to. But this all falls to bits if you want to run the same test simultaneously on the same machine, or you need lots of different ports during the course of one test.
At this point, you can reach for the port 0 trick: on both Windows and Linux, if you bind a socket to port 0, the kernel will assign it a free port number somewhere above 1024. Truly well-written software (e.g. Jetty) will not only let you configure it to bind to port 0, but will make it easy to parse its logs to obtain the actual port number it got assigned. Less helpful software (Tomcat) will let you configure it to bind to port 0, but print 0 in all its logs, never the actual number. And the majority of software just won’t let you put 0 as a port number in its configuration.
At this point (subject to a slight race condition), you can grab some port numbers yourself and feed them to whatever you’re trying to configure:
def findFreePorts(howMany=1): """Return a list of n free port numbers on localhost""" results = [] sockets = [] for x in range(howMany): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 0)) # work out what the actual port number it's bound to is addr, port = s.getsockname() results.append(port) sockets.append(s) for s in sockets: s.close() return results
The above is written in Python, but it translates trivially to any programming language which knows what a socket is.
You’ll note that the correct way to get, say, five free port numbers is to call the above method once with 5 as its argument. If you wrote a simple method which just returned one number, there would be nothing to stop it returning the same number each time you called it (the Linux kernel is rather more helpful, and will usually hand out a different number to each port 0 request, but I wouldn’t rely on this).
Post navigation
Recent Posts
Recent Comments
Archives
- February 2014
- January 2014
- December 2013
- September 2013
- August 2013
- April 2013
- December 2012
- November 2012
- October 2012
- August 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- December 2011
- October 2011
- September 2011
- August 2011
- July 2011
- June 2011
- May 2011
- March 2011
- February 2011
- December 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- January 2010
- December 2009
- November 2009
- October 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- June 2008
- May 2008
- March 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- July 2007
- June 2007
- May 2007