如果你的目标是简单地更新你的IP地址的服务器,那么你只需要使用一个典型的TCP套接字与此服务器的连接:
int sock = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in addrLocal = {};
result = connect(sock, (sockaddr*)&server_address, sizeof(server_address));
send(sock, "I have a new IP address", ...);
在上面的例子中,你不” t甚至必须在套接字上调用bind
,因为客户端TCP/IP协议栈会向您的计算机的路由表查询最佳本地IP地址以使用(并且将随机选择一个本地端口)。
客户端甚至不需要知道它所连接的IP地址,也不需要通过套接字协议告诉服务器。当服务器进行相应的接受呼叫时,服务器可以自动检测您的IP地址接收客户端连接。
sockaddr_in addrRemote = {};
socklen_t addrRemoteSize = sizeof(addrRemote);
int sockclient = accept(listensocket, (sockaddr*)&addrRemote, &addrRemoteSize);
// the IP address of the client making the connection is in addrRemote.
如果您的客户端只是保持套接字服务器开放,那么服务器可以传输文件返回给客户端,而无需建立新的连接或跟踪任何IP地址。
现在回答您的原始问题,以防您确实需要确定本地IP地址。
问题1:
要获得每个适配器的本地IP地址,你可以调用getifaddrs。从该函数返回的结果列表中,筛选出任何不是IP的地址,不是UP或LOOPBACK。
问题2:
将套接字绑定到特定的适配器,结合之前做出连接调用本地适配器的IP地址。实施例下面
...
result = bind(sock, (sockaddr*)&addr, sizeof(addr));
if (result != -1)
connect(sock, (sockaddr_in*)&remoteServer, sizeof(remoteServer));
其中“地址”上述各点的代码示例中由getifaddrs返回的ifaddr的阵列中的ifa_addr值之一。
现在,如果有任何这些连接涉及NAT,则您的本地枚举IP地址将与服务器看到您的公共IP地址不同。
如果您使用UDP套接字,那么上述所有东西仍然适用,并进行了一些调整。 (例如,不要调用connect(),只需调用sendto())。