C - Public IP from file descriptor

2019-08-01 00:20发布

I have three process in three different computers.

Process 1, the client, asks Process 2 for the IP and PORT of Process 3.

Process 3 connected to Process 2 earlier, and Process 2 gets the IP of Process 3 from the file descriptor (Process 3 already knows the ip and port of Process 2).

This works fine, but if I try to run Process 2 and Process 3 in the same computer, the IP of Process 3 is always 127.0.0.1 so Process 1 never finds Process 3.

    socklen_t len;
    struct sockaddr_storage addr;
    char ipstr[INET_ADDRSTRLEN];

    len = sizeof addr;
    getpeername(fd, (struct sockaddr*) &addr, &len);

    struct sockaddr_in *s = (struct sockaddr_in *) &addr;

    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);

This is the code I'm using, and ipstr is the IP I get.

How can I solve this?

Many thanks!

标签: c sockets ip
3条回答
成全新的幸福
2楼-- · 2019-08-01 00:21

If Process 3 is using 127.0.0.1, and Process 1 is on a different machine, then Process 1 would never be able to communicate with Process 3, as Process 3 would not have access to the network to begin with because 127.0.0.1 is isolated to just the local machine only. Process 3 would have to be using the machine's actual network IP instead in order to be reachable by other machines on the network.

查看更多
虎瘦雄心在
3楼-- · 2019-08-01 00:29

If after the getpeername() call for process 3 socket you detect that the address is the localhost, you can instead call getsockname() for the process 1 socket to get the IP process 1 used to connect to process 2. So long as process 3 is listening to the same interfaces as process 2 when they are running on the same machine, process 1 should be able to connect to process 3 with the same address.

len = sizeof addr;
getpeername(p3_socket, (struct sockaddr*) &addr, &len);
struct sockaddr_in *s = (struct sockaddr_in *) &addr;
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);

if (strcmp(ipstr, "127.0.0.1") == 0) {
    len = sizeof(addr);
    getsockname(p1_socket, (struct sockaddr *)addr, &len);
    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
}
查看更多
\"骚年 ilove
4楼-- · 2019-08-01 00:34

I don't know how process 2 connect process 3:

int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);

if the *serv_addr* argument in connect function is localhost, so process getpeername will get localhost, if the *serv_addr* is the IP of the PC,so you can get the IP of the PC.

查看更多
登录 后发表回答