【问题标题】:How can I get the connected host's IP address from a Windows Socket (C++)?如何从 Windows Socket (C++) 获取连接主机的 IP 地址?
【发布时间】:2011-10-02 10:38:03
【问题描述】:

我以前见过这个问题,但我从未找到有效的答案。我需要获取我的服务器连接到的计算机的显式 IP 地址(即 123.456.789.100)和端口号,以便将该信息转发给其他客户端。我在 Windows 7(家庭高级版)、Visual Studio 2010 Professional 上使用 WinSock2.h - 制作“C++ 控制台应用程序”。这是一个 TCP 连接。 到目前为止,这是我的代码:

sockaddr_in* addr = new sockaddr_in;
int addrsize = sizeof(addr);
getsockname(clientSock, (sockaddr*)addr, &addrsize);
char* ip = inet_ntoa(addr->sin_addr);
int port = addr->sin_port;
printf("IP: %s ... PORT:%d\n", ip, port);

这总是给我 205.205.205.205 的 IP 和 52685 的端口每次。我尝试了替代方案,包括 gethostbyname,它可以工作,但我需要实际的 IP 本身。我也试过用getpeername() 代替getsockname(),但结果是一样的。我在路由器后面,但到目前为止,我在同一台机器上同时使用服务器和客户端。

提前感谢您的任何帮助!

【问题讨论】:

    标签: c++ visual-studio-2010 networking ip-address winsock2


    【解决方案1】:

    getpeername() 是您要使用的函数。

    我在您的代码中看到的一些错误:

    1) 您在堆上分配地址。不需要这样做,只需声明“sockaddr_in addr;”而是在堆栈上,并将 &addr(而不是 addr)传递给您的 getpeername() 调用。

    2) addrsize 被设置为指针的大小(例如 4 或 8),而不是实际 sockaddr_in 的大小,这意味着...

    3) getsockname() 可能失败,但你不知道,因为

    4) 你没有检查 getsockname() 的返回值是否有错误,这意味着

    5) 您所看到的结果只是向您显示了在 getsockname()/getpeername() 调用之前 (*addr) 中的任何随机垃圾数据,因为调用失败而没有向 addr 结构写入任何内容。

    6) 哦,还有一件事……请务必将您对 addr.sin_addr 的引用包含在 ntohl() 调用中,并将您对 addr.sin_port 的引用包含在 ntohs() 调用中,否则您会得到它们在小端(阅读:基于英特尔的)计算机上运行时以大端形式运行,这不是您想要的。

    【讨论】:

    • 是的,你是对的,它抛出了一个错误,我还没有检查它。非常感谢,您的解决方案奏效了。
    【解决方案2】:

    是的,你是对的,它抛出了一个错误,我还没有检查它。非常感谢,您的解决方案奏效了。对我有用的最终代码如下:

    sockaddr_in addr;
    int addrsize = sizeof(addr);
    int result = getpeername(clientSock, (sockaddr*) &addr, &addrsize);
    printf("Result = %d\n", result);
    char* ip = inet_ntoa(addr.sin_addr);
    int port = addr.sin_port;
    printf("IP: %s ... PORT: %d\n", ip, port);
    

    这让我得到了正确的结果。我感谢您的帮助。谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-02
      • 2022-06-29
      • 1970-01-01
      • 2015-06-06
      • 2012-05-31
      • 2013-01-23
      • 1970-01-01
      相关资源
      最近更新 更多