繁体   English   中英

如何从 Windows 套接字 (C++) 获取连接主机的 IP 地址?

[英]How can I get the connected host's IP address from a Windows Socket (C++)?

我以前见过这个问题,但我从来没有找到有效的答案。 我需要获取我的服务器连接到的计算机的明确 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);

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

提前感谢您的任何帮助!

getpeername() 是您要使用的 function。

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

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() 调用中,否则您会将它们放在 big-在 little-endian(读取:基于 Intel)的计算机上运行时的 endian 形式,这不是您想要的。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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