6

I want my program to bind to a free port.

Google told me that a bind with port=0 will do that, but I haven't found if this is guaranteed to work on any system (Windows/Linux in particular).

Can someone link a doc that say that?

Ajay
  • 18,086
  • 12
  • 59
  • 105
MicheleA
  • 173
  • 1
  • 6
  • 1
    Shouldn't you skip the bind() call, if you want ephemeral port to be selected? – Code Painters May 05 '11 at 10:02
  • 2
    @CodePainters - not on a receiving socket, no. – Alnitak May 05 '11 at 10:08
  • @Alnitak Hmm, at least on Linux it works as I expected (just verified) - skipping bind(), and using socket()/listen()/accept() results in a listening socket using ephemeral port. I'm not sure about Win32, however. – Code Painters May 05 '11 at 14:24
  • yes, according to "TCP/IP Illustrated vol 2" it looks like the 4.2BSD code does an implicit bind to an ephemeral port if you don't bind yourself. – Alnitak May 05 '11 at 14:28
  • Why not just check the documentation? The answer is Yes to windows https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550(v=vs.85).aspx – Ben Sep 30 '15 at 15:59
  • @Alnitak `man 7 ip` says an ephemeral port is allocated on bind, listen, connect or sendto. – Goswin von Brederlow Feb 20 '19 at 10:33
  • I'm voting to close this question as off-topic because asking for documentation is out of the scope of this site. – Sterling Archer Mar 19 '19 at 15:57

4 Answers4

8

It's standard, documented behavior for AF_INET address family:

http://man7.org/linux/man-pages/man7/ip.7.html

See ip_local_port_range, which contains the following:

    An ephemeral port is allocated to a socket in the following circumstances:

          *  the port number in a socket address is specified as 0 when
             calling bind(2);
Jeff Learman
  • 2,914
  • 1
  • 22
  • 31
5

It's certainly "standard" in the 4.2BSD socket API from which most every other implementation is derived, but I'm not aware of any formal specification that actually says so.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
5

It's universal as far as I know, but I can't find any text in the standards that says it is. An alternative that might be more portable is using getaddrinfo with null service name pointers and the AI_PASSIVE flag. This is guaranteed to give you an sockaddr you can bind to. It's also the correct way to let the administrator choose which local ip (v4 or v6) address to bind to.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
0
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
int main()
{
    struct sockaddr_in addr;
    socklen_t addrLen;
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1) {
        printf("Failed to create socket");
    }
    addr.sin_family = AF_INET;
    addr.sin_port = 0; 
    addr.sin_addr.s_addr = INADDR_ANY; 
    if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) == -1) {
        printf("Failed to bind");
    }
    addrLen = sizeof(addr);
    if (getsockname(fd, (struct sockaddr *)&addr, &addrLen) == -1) {
        printf("getsockname() failed");
    }
    printf("port=%d \n", addr.sin_port);
    return 0;
}
  • 1
    The question is not “how might I write a program that attempts to bind to port 0?” but rather “is the behavior of binding to port 0 specified by any standard?”. This does not appear to answer the question. – wchargin Sep 19 '19 at 22:18