【问题标题】:C - Public IP from file descriptorC - 来自文件描述符的公共 IP
【发布时间】:2013-07-09 02:46:13
【问题描述】:

我在三台不同的计算机上有三个进程。

进程 1,客户端,向进程 2 询问进程 3 的 IP 和 PORT。

进程 3 早先连接到进程 2,进程 2 从文件描述符中获取进程 3 的 IP(进程 3 已经知道进程 2 的 ip 和端口)。

这工作正常,但如果我尝试在同一台计算机上运行进程 2 和进程 3,进程 3 的 IP 始终为 127.0.0.1,因此进程 1 永远找不到进程 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);

这是我使用的代码,ipstr是我得到的IP。

我该如何解决这个问题?

非常感谢!

【问题讨论】:

  • 如果IP是127.0.0.1,你的进程2可以查找本地机器的网络接口地址。但可能不止一个,它必须选择一个发送到进程 1。

标签: c sockets ip


【解决方案1】:

如果在getpeername()调用进程3套接字之后你检测到地址是本地主机,你可以改为调用进程1套接字的getsockname()来获取用于连接进程2的IP进程1。这么久由于进程 3 在同一台机器上运行时正在侦听与进程 2 相同的接口,因此进程 1 应该能够使用相同的地址连接到进程 3。

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);
}

【讨论】:

  • 进程 3 绑定到 127.0.0.1 的事实意味着它没有绑定到网络可访问的接口,因此进程 1 根本无法与进程 3 直接通信。跨度>
  • 进程 3 更有可能绑定到 INADDR_ANY 但使用 localhost 连接到进程 2。
  • 这并没有改变我所说的。一旦调用connect(),已建立的连接仍将仅绑定到 127.0.0.1,因此进程 1 将无法通过网络访问。
【解决方案2】:

如果进程 3 使用 127.0.0.1,而进程 1 在另一台机器上,那么进程 1 将永远无法与进程 3 通信,因为进程 3 将无法访问网络,因为 127.0. 0.1 仅与本地计算机隔离。进程 3 必须使用机器的实际网络 IP,才能被网络上的其他机器访问。

【讨论】:

    【解决方案3】:

    不知道进程2如何连接进程3:

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

    如果connect函数中的*serv_addr*参数是localhost,那么进程getpeername会得到localhost,如果*serv_addr*是PC的IP,那么你可以获取PC的IP。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-11
      • 1970-01-01
      • 2015-02-06
      • 2023-02-03
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      相关资源
      最近更新 更多