我以前看过这个问题,但从未找到有效的答案。我需要获取服务器所连接计算机的显式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和PORT的52685。我尝试了替代方法,包括gethostbyname,该方法可以工作,但我需要实际的IP本身。我也尝试过使用getpeername()代替getsockname(),但是结果是相同的。我在路由器后面,但到目前为止,我正在同一台计算机上同时使用服务器和客户端。
在此先感谢您提供的所有帮助!
最佳答案
getpeername()是您要使用的函数。
我在您的代码中看到一些错误:
1)您正在堆上分配addr。无需这样做,只需声明“sockaddr_in addr;”即可。相反,将&addr(而不是addr)传递给您的getpeername()调用。
2)addrsize被设置为指针的大小(例如4或8),而不是实际的sockaddr_in的大小,这意味着...
3)getsockname()可能会失败,但是您不知道那是因为
4)您不是要检查getsockname()的返回值以查看是否存在错误,这意味着
5)您看到的结果只是向您显示getockname()/ getpeername()调用之前(* addr)中的任何随机垃圾数据,因为该调用失败了,没有向addr结构写入任何内容。
6)哦,还有一件事...一定要在ntohl()调用中包装对addr.sin_addr的引用,并在ntohs()调用中包装对addr.sin_port的引用,否则您将获得大的包装。在小字节序(基于Intel的)计算机上运行时,字节序形式不是您想要的。
关于c++ - 如何从Windows套接字(C++)获取连接的主机的IP地址?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6644603/