49

I'm having trouble figuring this out - I'm working with sockets in C using this guide - http://binarii.com/files/papers/c_sockets.txt

I'm trying to automatically get my ip and port using:

server.sin_port = 0;              /* bind() will choose a random port*/
server.sin_addr.s_addr = INADDR_ANY;  /* puts server's IP automatically */
...
...
bind(int fd, struct sockaddr *my_addr,int addrlen); // Bind function

After a successful bind, how do I find out what IP and Port I'm actually assigned?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
stringo0
  • 2,720
  • 7
  • 38
  • 52
  • Actually what's happening when you specify `INADDR_ANY` isn't that it puts the server's IP in automatically, what it does is finds all interfaces, and binds to each one of them. Therefore, you have many right answers to your question. – jer Oct 28 '10 at 19:50
  • Hmm - thanks jer. An assignment I'm working on requires me to automatically obtain the IP and port using the code specified, but I'm to print the server address and port for the client to connect to on the screen. This is what I'm trying to figure out how to do. If I use the sockaddr struct, I just get 0.0.0.0 and port 0. – stringo0 Oct 28 '10 at 19:52
  • 1
    See http://stackoverflow.com/questions/2496302/how-can-i-obtain-the-local-tcp-port-and-ip-address-of-my-client-program – mark4o Oct 28 '10 at 19:55
  • 7
    Actually it doesn't 'bind to each one of them'. It doesn't bind to *any* of them. Rather it tells the stack to *act as though* it was bound to *all* of them. That's why it's called INADDR_ANY. – user207421 Oct 29 '10 at 11:35

2 Answers2

91

If it's a server socket, you should call listen() on your socket, and then getsockname() to find the port number on which it is listening:

struct sockaddr_in sin;
socklen_t len = sizeof(sin);
if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
    perror("getsockname");
else
    printf("port number %d\n", ntohs(sin.sin_port));

As for the IP address, if you use INADDR_ANY then the server socket can accept connections to any of the machine's IP addresses and the server socket itself does not have a specific IP address. For example if your machine has two IP addresses then you might get two incoming connections on this server socket, each with a different local IP address. You can use getsockname() on the socket for a specific connection (which you get from accept()) in order to find out which local IP address is being used on that connection.

mark4o
  • 58,919
  • 18
  • 87
  • 102
  • Thanks mark4o - That works great! But I'm still having trouble getting the address - I still get 0.0.0.0 - any ideas? Thanks! – stringo0 Oct 28 '10 at 23:41
  • 1
    The server socket does not have a specific IP address, and the machine may have multiple IP addresses. If you just want to get one of the machine's addresses, check out this other question: http://stackoverflow.com/questions/212528/linux-c-get-the-ip-address-of-local-computer – mark4o Oct 28 '10 at 23:53
  • 8
    Thanks for this code sample. If anyone is confused about what sock is, it is the file descriptor of the socket. – JustinDanielson Nov 28 '12 at 17:42
  • What about UDP: If I send on a socket that has Port `0` assigned, how can I find out what the sending port number actually is? (It is different from TCP) – U. Windl Jul 11 '18 at 07:26
  • 3
    Note that you do not have to actually call `listen`, this should work for both TCP and UDP sockets as long as they are bound first. – Andrew Sun Jul 11 '18 at 07:53
6

The comment in your code is wrong. INADDR_ANY doesn't put server's IP automatically'. It essentially puts 0.0.0.0, for the reasons explained in mark4o's answer.

Community
  • 1
  • 1
user207421
  • 305,947
  • 44
  • 307
  • 483