port 0 networking

Chris Nelson cites W. Richard Stevens as writing in his UNIX Network Programming that

The process can let the system automatically assign a port. For both the Internet domain and the XNS domain, specifying a port number of 0 before calling bind() requests the system to do this.

A variety of networking texts (most of them derivative of RFCs?) cite "0-1023" as reserved port numbers, without more comment.

CL believes the following are true:

  • A correctly implemented stack responds to a request to use port 0 by selection of a not-currently-in-use port, generally as low as possible.
  • Tcl is "passive", that is, simply inherits the behavior of the C API over which it is implemented.
  • All recent Tcl versions for Unix and Win* behave this way for port 0 requests.

We hope someone will test out a few Tcl versions under MacOS during October 2001.

Our experience on 'Windows isn't encouraging of using this technique. I'd forgotten why but poked around and found this in the bowels of one of our libraries:

    if { [string match $tcl_platform(platform) unix] } {
        # Specifying 0 as the port number tells socket to find a free
        # one
        if { [catch {socket -server $newClientCmd 0} sock] } {
            return 0
        } else {
            # -sockname returns address, hostname, and port number
            set port [lindex [fconfigure $sock -sockname] 2]
    } else {
        # On Microsoft Windows, dial-up networking may be invoked by
        # [fconfigure -sockname] so we iterate looking for a free port
        # rather than use 0 to have [socket] find one for us.

        for { set port 2000 } {$port < 32767 } {incr port } {
            if {[catch {socket -server $newClientCmd $port} sock]} {
        return 0

This code is 2-3 years old and stable. Does anyone know if the situation has changed? Has fconfigure -sockname been reimplemented in a friendlier fashion? -- CLN

DKF: The problem has to do with the way some winsock implementations do name resolution, which fconfigure -sockname triggers, and not the creation of the socket itself. Note that this is not universally true; none of my systems try this sort of thing.

Daniel Steffen reports that the MacOS is as it should be:

    "seems to work ok:

    % set tcl_platform(platform)
    % info patchlevel
    % fconfigure [socket -server blah 0] -sockname
    xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx 53433"

RLH works as it should on Windows XP as well:

    % set tcl_platform(platform)
    % info patchlevel
    % fconfigure [socket -server blah 0] -sockname 4728