**
如何重新设置一个网卡的IP地址
**
当内核基于某个IP地址运行一段时间后,该IP地址会在内核中留下许多足迹:ARP中会有该IP对应的缓存表项;Tcp连接控制块也会记录该IP地址。这时如果要重新设IP,不能以新的IP地址来调用内核初始化函(InitLwip),因为内核基于旧IP分配的资源并没有得到释放,严重的情况下,可能会导致内存访问错误,系统跑飞等现象。
网络接口管理函数中,有几个函数相当的重要,他们负责控制和维护网卡的状态,这些函数名称及功能如下表所示。其中netif_set_addr用于重设网卡的IP、网关和子网掩码三个地址,本质上它是通过分别调用netif_set_ipaddr、netif_set_gw、netif_set_mask三个函数来完成的。netif_set_up和netif_set_down为网卡启用和禁用网卡。从内核实现上看,禁用网卡会使ARP层清楚旧IP地址对的ARP缓存表项,而函数netif_set_ipaddr重新设置IP地址前,会将旧IP地址相关的所有Tcp连接的控制块全部删除,这样就保证了不会再有连接使用旧的IP地址发送数据。
注意,在重设IP地址的这种情况下,应用程序的连接自然也会被重置,内核会通知这种连接错误给应用程序,应用程序必须能检测并处理这种错误,并在适当地时候重新启动连接。
函数名称 | 功能 |
---|---|
netif_add | 向内核注册一个网络接口,设置网卡相关地址,并初始化 |
netif_remove | 向内核注销一个网络接口 |
netif_set_default | 设置系统默认网络接口 |
netif_set_addr | 重新设置网络接口的IP地址、网关地址和子网掩码 |
netif_set_ipaddr | 重新设置网络接口的IP地址 |
netif_set_gw | 重新设置网络接口的网关地址 |
netif_set_netmask | 重新设置网络接口的子网掩码 |
netif_set_up | 启用网卡 |
netif_set_down | 禁用网卡 |
netif_set_link_up | 网卡底层打开,表示网卡已经可正常进行链路数据的收发 |
netif_set_link_down | 网卡底层关闭,表示网卡不能再继续接收链路数据 |
void NetConfigUpdate(NETCONFIGMESG* sLocalMesg)
{
int i;
err_t err;
struct ip_addr ip_update;
struct ip_addr Mask_update;
struct ip_addr GW_updata;
IP4_ADDR(&ip_update,sLocalMesg->aSrcIP[0],sLocalMesg->aSrcIP[1],
sLocalMesg->aSrcIP[2],sLocalMesg->aSrcIP[3]);
IP4_ADDR(&Mask_update, sLocalMesg->aNetMask[0], sLocalMesg->aNetMask[1],
sLocalMesg->aNetMask[2], sLocalMesg->aNetMask[3]);
IP4_ADDR(&GW_updata, sLocalMesg->aGateWay[0], sLocalMesg->aGateWay[1],
sLocalMesg->aGateWay[2], sLocalMesg->aGateWay[3]);
u_byLocalIP[0]=sLocalMesg->aSrcIP[0];
u_byLocalIP[1]=sLocalMesg->aSrcIP[1];
u_byLocalIP[2]=sLocalMesg->aSrcIP[2];
u_byLocalIP[3]=sLocalMesg->aSrcIP[3];
for(i = 0; i < LWIP_MAX_CONNECT; i++)
{
if(u_sTcp_pcb[i] != NULL)
{
err = tcp_close(u_sTcp_pcb[i]);
if(err == ERR_OK)
u_sTcp_pcb[i] = NULL;
}
}
netif_set_down(&u_sNetif); //先禁用网卡
netif_set_gw(&u_sNetif, &GW_updata); //重新设置网关地址
netif_set_netmask(&u_sNetif, &Mask_update); //重新设置子网掩码
netif_set_ipaddr(&u_sNetif, &ip_update); //重新设置IP地址
// netif_set_addr(&u_sNetif, &ip_update, &Mask_update, &GW_updata);
netif_set_up(&u_sNetif); //启用网卡
}
版权声明:本文为zhaozhiyuan111原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。