大虾们,救救我吧
INT WSAStringToAddress(
LPTSTR AddressString,
INT AddressFamily,
LPWSAPROTOCOL_INFO lpProtocolInfo, //这个在哪里找啊???
LPSOCKADDR lpAddress, //
LPINT lpAddressLength
);
这个函数怎么用啊?下面是我的一部分程序:
unsigned long int addrs;
GetDlgItemText(IDC_ROUTE,m_PRINT); //m_PRINT是 CString型的,IDC_ROUTE是EDIT
框
WSAStringToAddress(m_PRINT,addrs,?, ?dest_addr,? 32);//这里的后三个参数不
知
flag=do_ping(addrs) ; //道怎么加 ???? if(flag)m_PRINT=m_PRINT+"正常";谢谢了,有哪位大虾会的告诉一下YE !!急啊!
清华大学计算中心 蒋东兴 多址广播(multicast,也译作多点传送或组播)是一种一对多的传输方式,传输发起者通过一次传输就将信息传送到一组接收者,与单点传送(unicast)和广播(broadcast)相对应。多址广播使用最广泛的是IP multicast,它标准IP网络层协议的扩展,由Steve Deering定义的Host Extensions for IP Multicasting(RFC 1112)奠定基础。IP Multicasting的定义为:到一个“主机组”的IP数据报的传送,主机组是由零个或多个用同一IP目的地址标识的主机集合。Multicast数据报被传递到其目的主机组的所有成员,并且同常规单点传送的IP数据报一样可靠。主机组的成员是动态的,也就是说,主机可以在任何时间加入或离开主机组。主机组中成员在位置上和数量上都没有限制,一个主机可以同时是一个以上主机组的成员。 在Windows Sockets 1.1中没有定义多址广播,因此,绝大多数Windows Sockets 1.1实现不支持多址广播。Windows Sockets 2为支持IP multicast而定义了一组新的与协议无关的多址广播应用程序接口,归纳起来可以用表1表示。表1 WinSock 2的多址广播APIWSAEnumProtocols()
检测多址广播支持
WSASocket()
指定多址广播类型
WSAJoinLeaf()
加入一个多址广播组并指定角色(发送者和/或接收者)
WSAIoctl() SIO_MULTICAST_SCOPE
设置IP生存时间
WSAIoctl() SIO_MULTIPOINT_LOOPBACK
禁止内部回送(loopback)
函数WSAEnumProtocols()返回当前系统中安装的协议的详细描述,这些信息存放在一个协议信息结构(WSAPROTOCOL_INFO)的数组中。在其中的域dwServiceFlags1中的一些标识指示此服务由IP/UDP协议提供,并且位标识XP1_SUPPORT_MULTIPOINT指示该服务支持IP multicast。 为了适用不同的多址广播模式,WinSock 2定义了数据平面(data plane)和控制平面(control plane)两个概念,每一个平面都可以是“有根(rooted)”的或“无根(non-rooted)”的。关于这些概念的详细解释,参见WinSock 2规范附录B。IP multicast是一种无根的数据平面和控制平面。在使用WSASocket()函数请求一个多址广播套接字时需要指定这些角色。这通过在WSASocket()函数的参数dwFlags中使用四个标志位来实现:· WSA_FLAG_MULTIPOINT_C_ROOT,用来创建一个作为c_root节点的套接字,并且只有在相应的WSAPROTOCOL_INFO入口中指示了使用rooted控制平面时才允许。· WSA_FLAG_MULTIPOINT_C_LEAF,用来创建一个作为c_leaf节点的套接字,并且只有在相应的WSAPROTOCOL_INFO入口中指示了XP1_SUPPORT_MULTIPOINT时才允许。· WSA_FLAG_MULTIPOINT_D_ROOT,用来创建一个作为d_root节点的套接字,并且只有在相应的WSAPROTOCOL_INFO入口中指示了使用rooted数据平面时才允许。· 用来创建一个作为d_leaf节点的套接字,并且只有在相应的WSAPROTOCOL_INFO入口中指示了XP1_SUPPORT_MULTIPOINT时才允许。 注意,在IP multicast中,只有标志WSA_FLAG_MULTIPOINT_C_LEAF 和WSA_FLAG_MULTIPOINT_D_LEAF能用来作为WSASocket()函数的dwFlags参数。 WSAIoctl()函数的SIO_MULTIPOINT_LOOP命令码用来设置是否允许内部回送。当d_leaf套接字用于non-rooted数据平面时,它通常是希望能够控制发送出去的通信流量是否能够在同一个套接字上也被接收。WSAIoctl()函数的SIO_MULTIPOINT_LOOP命令码用来允许或禁止多址广播的通信流量的内部回送。 WSAIoctl()函数的SIO_MULTICAST_SCOPE命令码用来设置多址广播范围。当使用多址广播时,常常需要指定多址广播传播的范围。范围由包括的路由网段来定义。范围为0指示多址广播不传播信息到“网线”上,但是可以在本地主机的多个套接字间传播。范围为1(默认值)指示将传播信息到“网线”上,但是不跨越路由器。更高的范围值决定了可以跨越的路由器数量。注意这相当于IP multicast的生存时间(time-to-live,TTL)。 WSAJoinLeaf()函数用来加入一个叶子节点到多址广播会话,其函数原型为:SOCKET WSAAPI WSAJoinLeaf ( SOCKET s, const struct sockaddr FAR * name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, DWORD dwFlags );WSAJoinLeaf()具有与WSAConnect()相同的参数和语法,除了它还返回一个套接字描述符(这和函数WSAAccept()一样)及多了一个dwFlags参数外。参数dwFlags用来指示套接字是用来作为发送者还是接收者还是两者兼具。在此函数中,只有多址广播套接字可以用来作为输入参数s。如果此多址广播套接字处于非阻塞模式,返回的套接字描述符只有在接收到相应的FD_CONNECT指示后才能使用。参数name指示套接字将加入的多址广播的地址。 另外,在上面的API中没有提到如何离开一个多址广播组。唯一与协议无关的API是关闭套接字,即使用标准的closesocket()函数,它可以用来离开多址广播组。 Windows 95不支持IP multicast,如果要在Windows 95 上开发IP multicast程序,需要下载WinSock 2的软件开发包WS295SDK,这可以通过Internet免费下载。相关站点地址为:http://www.microsoft.com/win32dev/netwrk/winsock2/ws295sdk.html。Windows 98支持IP multicast,如果使用Windows 98,则不必运行其中的ws2setup.exe。 下面给出一个简单的例子说明WinSock 2多址广播程序的设计。 #include <winsock2.h>#include <stdio.h> #define BUFSIZE 1024#define MAXADDRSTR 16#define LOOPCOUNT 100 /* 检查系统中是否安装了合适版本的WinSock DLL。 */ int CheckWinsockVersion(VOID) { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 2); // 异步I/O和多址广播只有在WinSock 2.0以上版本才支持 err = WSAStartup(wVersionRequested, &wsaData); if (err==0) { if ((LOBYTE(wsaData.wVersion)==2) && (HIBYTE(wsaData.wVersion)==2)) // 确认WinSock DLL支持2.0 return 0; /* WinSock DLL可接受,成功返回 */ WSACleanup(); err = WSAVERNOTSUPPORTED; /* 不支持,失败返回 */ } /* Tell the user that we couldn't find a usable WinSock DLL.*/ printf("WinSock DLL does not support requested API version.\n"); return err;} int main() { int nRet, i; int nIP_TTL = 1; // 在本子网中传播。如果要跨路由器,则路由器必须支持IGMP协议 BOOL bFlag; DWORD dFlag, cbRet; int iLen = MAXADDRSTR; char strDestMulti[MAXADDRSTR] = "224.1.1.1"; // 多址广播地址范围从224到239。 SOCKADDR_IN stSrcAddr, stDestAddr; SOCKET hSock, hNewSock; u_short nDestPort = 6666; WSABUF stWSABuf; char achInBuf [BUFSIZE]; char achOutBuf[] = "Message number: "; nRet = CheckWinsockVersion(); // 检查WinSock版本号 if (nRet) { printf ("WSAStartup failed: %d\r\n", nRet); exit (1); } // 将字符串地址转换为套接字地址 nRet = WSAStringToAddress ( strDestMulti, /* address string */ AF_INET, /* address family */ NULL, /* protocol info structure */ (LPSOCKADDR)&stDestAddr, /* socket address string */ &iLen); /* length of socket structure */ if (nRet) { printf ("WSAStringToAddress(%s) failed, Err: %d\n", strDestMulti, WSAGetLastError()); exit(1); } // 创建一个多址广播套接字hSock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, (LPWSAPROTOCOL_INFO)NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF); if (hSock == INVALID_SOCKET) { printf ("WSASocket() failed, Err: %d\n", WSAGetLastError()); exit (1); } bFlag = TRUE; // 设置套接字为可重用端口地址 nRet = setsockopt(hSock, /* socket */ SOL_SOCKET, /* socket level */ SO_REUSEADDR, /* socket option */ (char *)&bFlag, /* option value */ sizeof (bFlag)); /* size of value */ if (nRet == SOCKET_ERROR) printf("setsockopt() SO_REUSEADDR failed, Err: %d\n", WSAGetLastError());
closesocket(hNewSock); closesocket(hSock);
// 卸载WinSock DLL WSACleanup();
return (0);} /* end main() */