2011-07-11 149 views
1

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

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(),但结果是相同的。我在路由器后面,但到目前为止,我在同一台计算机上同时使用了服务器和客户端。

在此先感谢您的帮助!

回答

3

getpeername()是你想要使用的函数。

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

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

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

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

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

5)结果在getsockname()/ getpeername()调用之前,看到的只是显示任意垃圾数据(* addr),因为调用失败而没有向广告写入任何内容dr结构。噢,还有一件事......一定要在ntohl()调用中包含对addr.sin_addr的引用,并且在ntohs()调用中引用addr.sin_port,否则您将获得它们在运行小端(基于英特尔架构)计算机时以大端形式存在,这不是您想要的。

+0

是的,你是对的,它是抛出一个错误,我没有检查它。非常感谢您的解决方案。 – Sefu

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

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

相关问题