问题背景
项目中由于需要使用多播编程技术,在调试调试初期出现过服务端无法监听到客户端请求,因此写了setsockopt设置多播属性失败的解决方法这篇文章。在后续进一步测试过程中,还陆陆续续出现出现10065和10049的socket error,发生错误的代码均在socket设置多播组属性,代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13//加入多播组 struct ip_mreq stMreq; //IP multicast address of group stMreq.imr_multiaddr.s_addr = inet_addr("239.1.100.1"); //Local IP address of interface stMreq.imr_interface.s_addr=htonl(INADDR_ANY); //发生错误的语句 iResult = setsockopt(RecvSocket,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&stMreq,sizeof(stMreq)); if (SOCKET_ERROR == iResult) { printf("add group socket error %d...n",::WSAGetLastError()); }
错误码含义如下:
通过错误码分析,错误原因均和网络有关系,后面通过分析或许和这以下两点有关系:
- 该虚拟机初始IP地址是
127.0.0.1
,过一段时间网络地址才变成正常的局域网地址 - 该监听线程是在window服务中进行,在虚拟机IP地址正常之前已经完成socket的创建以及绑定。
解决方法
虽然无法从根源上分析,为什么和网络地址有直接关系,但是从后续的实验验证表明,出现以上的原因就是因为本地IP地址变化或者网络处于非连接状态导致的。因此,可以从以下两个方面来保证虚拟机的网络状态ok,确保服务端监听流程正常进行。
方面一:
通过gethostname以及gethostbyname两个系统API来获取本地IP地址,直到其IP不是127.0.0.1
, 伪代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16while(1) { char szHostIP[128] = {} if (GetLocalhostIP(szHostIP)) { if (strcmp(szHostIP,"127.0.0.1") != 0) { break; } } else { Sleep(1000); } }
GetLocalhostIP实现参见GitHub。
方面二 :
当IP地址正常之后,再次通过isNetworkAlive
windows API 检测当前系统网络是否可连接。当IsNetworkAlive返回TRUE时,表明当前系统网络已经处于连接状态,可以进行后续的TCP/IP的网络操作。
最后
以上就是忐忑灯泡最近收集整理的关于因网络问题导致ADD_MEMBERSHIP失败的解决方法的全部内容,更多相关因网络问题导致ADD_MEMBERSHIP失败内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复