setsockopt设置组播返回10042(WSAENOPROTOOPT)错误
在编写组播程序时,需要加入组播组,调用setsockopt设置IP_ADD_MEMBERSHIP,代码如下:
/* join a multicast group */ if (multiaddr) { struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr(multiaddr); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) < 0) { printf("setsockopt error, code;"<<WSAGetLastError()); } }
调用setsockopt失败,返回错误号10042,后来发现程序默认使用的是Winsock.h头文件,在该头文件中IP_ADD_MEMBERSHIP的值为5
#define IP_OPTIONS 1 /* set/get IP per-packet options */ #define IP_MULTICAST_IF 2 /* set/get IP multicast interface */ #define IP_MULTICAST_TTL 3 /* set/get IP multicast timetolive */ #define IP_MULTICAST_LOOP 4 /* set/get IP multicast loopback */ #define IP_ADD_MEMBERSHIP 5 /* add an IP group membership */ #define IP_DROP_MEMBERSHIP 6 /* drop an IP group membership */ #define IP_TTL 7 /* set/get IP Time To Live */ #define IP_TOS 8 /* set/get IP Type Of Service */ #define IP_DONTFRAGMENT 9 /* set/get IP Don't Fragment flag */
而实际要使用的IP_ADD_MEMBERSHIP值是定义在Ws2tcpip.h头文件中
#define IP_MULTICAST_IF 9 /* set/get IP multicast i/f */ #define IP_MULTICAST_TTL 10 /* set/get IP multicast ttl */ #define IP_MULTICAST_LOOP 11 /*set/get IP multicast loopback */ #define IP_ADD_MEMBERSHIP 12 /* add an IP group membership */ #define IP_DROP_MEMBERSHIP 13/* drop an IP group membership */ #define IP_DONTFRAGMENT 14 /* don't fragment IP datagrams */
所以需要显示的引入Ws2tcpip.h头文件,使用该文件中定义的IP_ADD_MEMBERSHIP值,即可解决报10042错误的问题。