我正在尝试模拟在机器(笔记本电脑/PC)上运行的网络客户端(最好是C代码)。在启动时,它通过DHCP从机器所在网络的路由器协商一个新的IP地址。在获取IP地址后,假设根据配置文件进行http请求(下载/上传)。
设置主要是为了生成多个这样的客户端,以便对路由器进行压力测试。
我遇到了https://github.com/saravana815/dhtest,它做DHCP协商的一部分。它创建一个随机的mac地址&从路由器获取相同的IP。
下一步是扩展客户端以具有http调用。我开始查看https://github.com/jay/wget &标志--bind-address
引起了我的注意
--bind-address=ADDRESS bind to ADDRESS (hostname or IP) on local host.n"),
我所理解的是-这个标志的目的是在机器上选择合适的接口。仔细查看源代码,我发现下面的代码片段是为
标志而启动的。static bool
resolve_bind_address (struct sockaddr *sa)
{
struct address_list *al;
/* Make sure this is called only once. opt.bind_address doesn't
change during a Wget run. */
static bool called, should_bind;
static ip_address ip;
if (called)
{
if (should_bind)
sockaddr_set_data (sa, &ip, 0);
return should_bind;
}
called = true;
al = lookup_host (opt.bind_address, LH_BIND | LH_SILENT);
if (!al)
{
/* #### We should be able to print the error message here. */
logprintf (LOG_NOTQUIET,
_("%s: unable to resolve bind address %s; disabling bind.n"),
exec_name, quote (opt.bind_address));
should_bind = false;
return false;
}
/* Pick the first address in the list and use it as bind address.
Perhaps we should try multiple addresses in succession, but I
don't think that's necessary in practice. */
ip = *address_list_address_at (al, 0);
address_list_release (al);
sockaddr_set_data (sa, &ip, 0);
should_bind = true;
return true;
}
函数sockaddr_set_data (sa, &ip, 0);
如下图
static void
sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
{
switch (ip->family)
{
case AF_INET:
{
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
xzero (*sin);
sin->sin_family = AF_INET;
sin->sin_port = htons (port);
sin->sin_addr = ip->data.d4;
break;
}
#ifdef ENABLE_IPV6
case AF_INET6:
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
xzero (*sin6);
sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons (port);
sin6->sin6_addr = ip->data.d6;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
sin6->sin6_scope_id = ip->ipv6_scope;
#endif
break;
}
#endif /* ENABLE_IPV6 */
default:
abort ();
}
}
我不是一个确切的网络/插座专家。我想确认的是-明确添加IP地址到Wget发送的数据包将覆盖IP地址,操作系统将为这些数据包设置当他们离开一个特定的接口?
这个问题的答案将帮助我决定是否应该为我想要模拟的每个网络客户端创建一个单独的逻辑接口,或者我是否可以完全取消它(我更喜欢后者)。
数据包将通过套接字绑定的接口路由。IP地址可以是虚IP地址,也可以是以太网接口的主IP地址。IP决定了使用哪个物理接口进行通信。
您可以在给定的物理接口上创建多个虚拟IP地址,并生成每个绑定到不同IP的客户端。这为您的路由器提供了一个不同的源(模拟),尽管所有源都将使用相同的物理接口。