设置或获取套接字选项在 C/C++ Winsock 应用程序针对 Windows NT、 Windows 2000、 Windows 95 或 Windows 98 中 IPPROTO_IP 级别时, 程序项目中包括正确的标头和库文件至关重要。 如果标头和库文件不正确地匹配,setsockopt 或 getsockopt 可能会因运行时错误 10042 (WSAENOPROTOOPT)。 in certain cases,even if API returns successfully,that set or get option value may not be what would have expected。
若要避免此问题,遵守以下准则:
若要避免此问题,遵守以下准则:
? | 与 Wsock32.lib 应该只链接,其中包括 Winsock.h 程序。 |
? | 其中包括 Ws2tcpip.h 程序可能会链接与 Ws2_32.lib 或 Wsock32.lib。 请注意 Ws2tcpip.h 必须是显式包含 Winsock 2 h 后才能在此级别使用套接字选项。 |
更多信息
IPPROTO_IP 级别的套接字选项是在比 Winsock.h 的 Ws2tcpip.h 中以不同的方式定义的。 在 Winsock.h,定义是:
相比之下,作为 Ws2tcpip.h 中定义此级别的选项:
如果您不能正确匹配头和库文件,setsockopt 或 getsockopt 可能会因运行时错误 10042 (WSAENOPROTOOPT) 或者您设置或获取选项值不是您将有预期。
假定您想加入多路广播的组通过运行代码与以下内容类似:
请注意这包括 Winsock.h。 如果该项目已链接与 Ws2_32.lib,setsockopt 将失败,并运行时错误 10042 (WSAENOPROTOOPT)。 这是因为在 Winsock.h,IP_ADD_MEMBERSHIP 被定义为"5"。 相应的 Winsock 运行库不可以解决选项在 IPPROTO_IP 级别,5 以便,错误代码 10042 出现故障。
/* * Options for use with [gs]etsockopt at the IP level. */ #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 */ #define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */ #define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */ #define IP_MAX_MEMBERSHIPS 20 /* per socket; must fit in one mbuf */
相比之下,作为 Ws2tcpip.h 中定义此级别的选项:
/* Option to use with [gs]etsockopt at the IPPROTO_IP level */ #define IP_OPTIONS 1 /* set/get IP options */ #define IP_HDRINCL 2 /* header is included with data */ #define IP_TOS 3 /* IP type of service and preced*/ #define IP_TTL 4 /* IP time to live */ #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 */
如果您不能正确匹配头和库文件,setsockopt 或 getsockopt 可能会因运行时错误 10042 (WSAENOPROTOOPT) 或者您设置或获取选项值不是您将有预期。
case 1。 Runtime error 10042 (WSAENOPROTOOPT)
属于此类别的选项包括:
IP_ADD_MEMBERSHIPIP_DROP_MEMBERSHIPIP_TTLIP_TOS
假定您想加入多路广播的组通过运行代码与以下内容类似:
#include <stdio.h>#include <stdlib.h>#include <winsock.h>int main(int argc, char* argv[]){ ... ... ... if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&mreq, sizeof (mreq)) == SOCKET_ERROR) { printf ("setsockopt failed: %d"), WSAGetLastError()); closesocket (sock); return FALSE; } ... ... ...}
请注意这包括 Winsock.h。 如果该项目已链接与 Ws2_32.lib,setsockopt 将失败,并运行时错误 10042 (WSAENOPROTOOPT)。 这是因为在 Winsock.h,IP_ADD_MEMBERSHIP 被定义为"5"。 相应的 Winsock 运行库不可以解决选项在 IPPROTO_IP 级别,5 以便,错误代码 10042 出现故障。
case 2。 options set or get appear do not take effect
属于此类别的选项包括: IP_MULTICAST_TTL 作为示例。 在 Winsock.h,IP_MULTICAST_TTL 被定义为"3"。 在 ws2tcpip.h,该常量被定义为"10"并且 IP_TOS 被定义为"3"。 尝试更改默认的 TTL 值:
#include <stdio.h>#include <stdlib.h>#include <winsock.h>int main(int argc, char* argv[]){ int ttl = 7 ; // Arbitrary TTL value. ... ... ... source_sin.sin_family = AF_INET; source_sin.sin_port = htons(0); source_sin.sin_addr.s_addr = htonl (INADDR_ANY); if (bind(sock, (struct sockaddr FAR *)&source_sin, sizeof(source_sin)) == SOCKET_ERROR) { printf ("bind() failed: %d"), WSAGetLastError()); closesocket (sock); return FALSE; } if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl))) == SOCKET_ERROR) { printf ("setsockopt failed: %d"), WSAGetLastError()); closesocket (sock); return FALSE; } ... ... ...}
如果您链接与 Ws2_32.lib 该项目并运行该应用程序,使用 IP_MULTICAST_TTL setsockopt 将成功。 但是,多播的 TTL 设置不会生效。 如果您检查网络跟踪,您将看到 TTL 值仍保持为"1"(默认值)。
转自:http://hi.baidu.com/yiouzhou/blog/item/38421358134b4dd89c820432.html
IP_MULTICAST_IFIP_MULTICAST_TTLIP_MULTICAST_LOOPIP_DONTFRAGMENT