c++socketsberkeley-sockets

Generation of unique IP-port using bind(0)


I need to generate port numbers for some programm. Google tells, that bind with zero-port generates binds unused port. I want to bind zero-port, remember it's number, close port. Trying to do this? but netstat doesn't see my programm's port. Linux 2.6.27

int sfd;
struct sockaddr_in my_addr;

sfd = socket(PF_INET , SOCK_STREAM, 0);
if (sfd == -1)
{
    printf("socket error\n");
    return -1;
}

memset(&my_addr, 0, sizeof(struct sockaddr_in ));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = INADDR_ANY;
my_addr.sin_port = 0;

if (bind(sfd, (struct sockaddr_in *) &my_addr,
        sizeof(struct sockaddr_in)) == -1)
    printf("bind error\n");

if (listen(sfd, LISTEN_BACKLOG) == -1)
    printf("listen error\n");

Solution

  • bind() expects a sockaddr* not a sockaddr_in*:

    bind(sfd, (struct sockaddr *) &my_addr, sizeof(my_addr))
    

    Other than that, I don't see any other errors. Binding to port 0 is the correct way to bind to a random available port. If bind() and listen() do not report a failure then netstat should see an open port. Use getsockname() to find out which port bind() actually chose, eg:

    int sfd = socket(PF_INET , SOCK_STREAM, 0);
    if (sfd == -1)
    {
        printf("socket error: %d\n", errno);
        return -1;
    }
    
    struct sockaddr_in my_addr;
    memset(&my_addr, 0, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_addr.s_addr = INADDR_ANY;
    my_addr.sin_port = 0;
    
    if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(my_addr)) == -1)
    {
       printf("bind error: %d\n", errno);
       close(sfd);
       return -1;
    }
    
    if (listen(sfd, LISTEN_BACKLOG) == -1)
    {
        printf("listen error: %d\n", errno);
        close(sfd);
        return -1;
    }
    
    memset(&my_addr, 0, sizeof(my_addr));
    socklen_t my_addrlen = sizeof(my_addr);
    
    if (getsockname(sfd, (struct sockaddr *) &my_addr, &my_addrlen ) == -1)
    {
        printf("getsockname error: %d\n", errno);
        close(sfd);
        return -1;
    }
    
    printf("listening on port: %hu\n", ntohs(my_addr.sin_port));