2.2.2 小试牛刀--模拟实现Windows的UDP程序(10)
(7) 多播功能控制模块
多播功能控制模块是为多播发送模块和多播接收模块服务的,它实现多播的套接创建和绑定功能、套接字选项设置功能、多播组加入功能等。具体实现代码如下:
- /*多播控制函数*/
- void mulControl()
- {
- int optval;
- /*创建UDP套接字,用于多播*/
- if ((socketMul = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0,
- WSA_FLAG_MULTIPOINT_C_LEAF
- | WSA_FLAG_MULTIPOINT_D_LEAF
- | WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
- {
- printf("socket failed with: %d\n", WSAGetLastError());
- WSACleanup();
- return;
- }
-
- /*设置本地接口地址*/
- addrLocal.sin_family = AF_INET;
- addrLocal.sin_port = htons(mPort);
- addrLocal.sin_addr.s_addr = dwInterface;
-
- /*将UDP套接字绑定到本地地址上*/
- if (bind(socketMul, (struct sockaddr *)&addrLocal,
- sizeof(addrLocal)) == SOCKET_ERROR)
- /*如果绑定失败*/
- {
- printf("bind failed with: %d\n", WSAGetLastError());
- closesocket(socketMul);
- WSACleanup();
- return;
- }
-
- /*设置多播地址各个选项*/
- addrMul.sin_family = AF_INET;
- addrMul.sin_port = htons(mPort);
- addrMul.sin_addr.s_addr = dwMulticastGroup;
-
- /*重新设置TTL值*/
- optval = 8;
- /*设置多播数据的TTL(存在时间)值。默认情况下,TTL值是1*/
- if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_TTL,
- (char*)&optval, sizeof(int)) == SOCKET_ERROR)
- /*如果设置失败*/
- {
- printf("setsockopt(IP_MULTICAST_TTL) failed: %d\n",
- WSAGetLastError());
- closesocket(socketMul);
- WSACleanup();
- return;
- }
-
- /*如果指定了返还选项*/
- if (bLoopBack)
- {
- /*设置返还选项为假,禁止将发送的数据返还给本地接口*/
- optval = 0;
- if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_LOOP,
- (char*)&optval, sizeof(optval)) == SOCKET_ERROR)
- /*如果设置失败*/
- {
- printf("setsockopt(IP_MULTICAST_LOOP) failed: %d\n",
- WSAGetLastError());
- closesocket(socketMul);
- WSACleanup();
- return;
- }
- }
-
- /*加入多播组*/
- if ((sockJoin=WSAJoinLeaf(socketMul, (SOCKADDR*)&addrMul,
- sizeof(addrMul), NULL, NULL, NULL, NULL,
- JL_BOTH)) == INVALID_SOCKET)
- /*如果加入不成功*/
- {
- printf("WSAJoinLeaf() failed: %d\n", WSAGetLastError());
- closesocket(socketMul);
- WSACleanup();
- return;
- }
- }