我有一台带有 2以太网适配器的Linux计算机。我还有 2个ADSL型号和 2个互联网连接。我将调制解调器A连接到以太网端口A,将调制解调器B连接到以太网端口B.
现在,如何执行以下操作(最好在 C ++ 中):
a)获取每个适配器的IP
b)选择要使用的连接进行下载(我想说:使用连接A下载此文件,将此文件与B一起下载)
IP 动态。我这样做,因为我的IP必须知道远程服务器。
服务器必须:
a)获取IP
b)发送文件到此IP
我的想法是,每次我的IP更改时,我都会将新IP发送到服务器,因此服务器将知道将文件发送到何处。
我使用2个互联网连接:
a)冗余原因(如果一个互联网连接断开,我得到第二个)
b)通过打开与服务器的2个连接来提高下载速度。
答案 0 :(得分:2)
如果您的目标只是更新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", ...);
在上面的示例中,您甚至不必在套接字上调用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));
上面代码示例中的“addr”指向getifaddrs返回的ifaddr数组中的ifa_addr值之一。
现在,如果这些连接中涉及NAT,那么您本地枚举的IP地址将与服务器看到您的公共IP地址不同。
如果您使用的是UDP套接字,那么上述所有内容仍然适用,并进行了一些调整。 (例如,不要调用connect(),只需调用sendto())。