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

时间:2011-07-11 00:11:01

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

我以前见过这个,但我从来没有找到一个有效的答案。我需要获取显式IP地址(即123.456.789.100)和我的服务器所连接的计算机的PORT号,以便将该信息转发给其他客户端。我在Windows 7(Home Premium)上使用WinSock2.h,Visual Studio 2010 Professional - 制作“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,每次给PORT 52685。我尝试了替代方案,包括gethostbyname,它可以工作,但我需要实际的IP本身。我也试过getpeername()代替getsockname(),但结果是一样的。我在路由器后面,但到目前为止我在同一台机器上同时使用服务器和客户端。

提前感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:3)

getpeername()是您要使用的功能。

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

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

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

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

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

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

6)哦,还有一件事......确保在ntohl()调用中包含对addr.sin_addr的引用,以及在ntohs()调用中对addr.sin_port的引用,或者你会得到它们以小端形式运行时(读取:基于Intel的)计算机,这不是你想要的。

答案 1 :(得分:1)

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

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

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