局域网发现协议
局域网发现协议
网关和手机之间的发现协议应该用一个可以自动匹配IP的方式。
比如说,网关刚开始是处于路由模式的,那么它的IP地址可能是192.168.1.1,当用户将它切换成STA模式或者说桥接模式时,它的IP地址一定会变化,那么这个时候手机就无法获取设备的IP了。
网上经常说用组播去做发现协议,但是我经过测试后发现,组播只适用于一般的场景,比如手机只会连接网关,或者说只会去连接它的上级路由。因为组播协议在路由端会遇到路由的不同处理,有的可能无法出局域网导致无法发现。
组播想发送到自己的子网需要添加下面一条路由 协议:
route add -net 224.0.0.0 netmask 224.0.0.0 dev br-lan此路由协议后面的接口改一下的话同样适用于上级路由。
组播的代码如下:
初始化
if(-1 == (sIotcMulticast.iSocketFd = socket(AF_INET, SOCK_DGRAM, 0)))
{
ERR_vPrintf(T_TRUE, "socket create error %s\n", strerror(errno));
return E_MULTI_ERROR_CREATESOCK;
}
int on = 1; /*SO_REUSEADDR port can used twice by program */
if((setsockopt(sIotcMulticast.iSocketFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))<0)
{
ERR_vPrintf(T_TRUE,"setsockopt failed, %s\n", strerror(errno));
close(sIotcMulticast.iSocketFd);
return E_MULTI_ERROR_SETSOCK;
}
sIotcMulticast.server_addr.sin_family = AF_INET;
sIotcMulticast.server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
sIotcMulticast.server_addr.sin_port = htons(iPort);
if(-1 == bind(sIotcMulticast.iSocketFd,
(struct sockaddr*)&sIotcMulticast.server_addr, sizeof(sIotcMulticast.server_addr)))
{
ERR_vPrintf(T_TRUE,"bind socket failed, %s\n", strerror(errno));
close(sIotcMulticast.iSocketFd);
return E_MULTI_ERROR_BIND;
}
sIotcMulticast.multi_addr.imr_multiaddr.s_addr = inet_addr(paMulAddress);
sIotcMulticast.multi_addr.imr_interface.s_addr = htonl(INADDR_ANY);
if(setsockopt(sIotcMulticast.iSocketFd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char *)&sIotcMulticast.multi_addr, sizeof(sIotcMulticast.multi_addr)) < 0)
{
ERR_vPrintf(T_TRUE,"setsockopt failed, %s\n", strerror(errno));
close(sIotcMulticast.iSocketFd);
return E_MULTI_ERROR_SETSOCK;
}然后起一个线程作为服务器,等待手机发送请求,收到请求后随便回复一个什么值,手机会根据这个包去解析出IP,无需显式的发送:
手机端代码:
================================================================================================
上面的组播经测试发现并不好用,网段一变就无法连接,下面介绍广播的方式。
广播的客户端代码:
线程体:
手机端代码,因为广播的数据会马上被路由转发,所以手机自己会收到自己的数据,需要重复收听直到收到服务端响应:
最后更新于
这有帮助吗?