简体   繁体   中英

IP address in TCP sockets

I have a root node(server) connected to many other nodes(clients) through TCP sockets. I want to send some data from server to client, but the data is different for each node and depends on the ip address of that node.

Thus I should have ip address of each node connected to server. How can I have that information?

When you call accept(2) you can choose to retrieve the address of the client.

int accept(int socket, struct sockaddr *restrict address,
    socklen_t *restrict address_len);

You need to store those addresses and then send(2) to each what you need to send.

So the workflow should be something like this:

  • Keep a list of connected clients. Initially the list is empty, of course
  • When you accept a connection, push its details into that list (the address and the socket returned by accept(2) ).
  • When you need to send something to every client, simply walk the list and send it (using the stored socket)

The one tricky part is that socklen_t *restrict address_len is a value-result argument, so you need to be careful with that.

This is a more nuanced question than it first appears.

If the clients are sitting behind a NAT, you may get the same IP from more than one client. This is perfectly natural and expected behavior. If you need to distinguish between multiple clients behind the same NAT, you'll need some other form of unique client id (say, IP address and port).

As long as you have access to the list of file descriptors for the connected TCP sockets, it is easy to retrieve the addresses of the remote hosts. The key is the getpeername() system call, which allows you to find out the address of the remote end of a socket. Sample C code:

// This is ugly, but simpler than the alternative
union {
    struct sockaddr sa;
    struct sockaddr_in sa4;
    struct sockaddr_storage sas;
} address;
socklen_t size = sizeof(address);

// Assume the file descriptor is in the var 'fd':
if (getpeername(fd, &address.sa, &size) < 0) {
    // Deal with error here...
}

if (address.sa.family == AF_INET) {
    // IP address now in address.sa4.sin_addr, port in address.sa4.sin_port
} else {
    // Some other kind of socket...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM