概述
问题背景
项目中由于需要使用多播编程技术,在调试调试初期出现过服务端无法监听到客户端请求,因此写了setsockopt设置多播属性失败的解决方法这篇文章。在后续进一步测试过程中,还陆陆续续出现出现10065和10049的socket error,发生错误的代码均在socket设置多播组属性,代码如下:
//加入多播组
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
, 伪代码如下:
while(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失败的解决方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复