>>分享Java编程技术,对《Java面向对象编程》等书籍提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 28939 个阅读者 刷新本主题
 * 贴子主题:  windows下UDP组播 回复文章 点赞(0)  收藏  
作者:日月光华    发表时间:2019-11-03 19:05:04     消息  查看  搜索  好友  邮件  复制  引用

windows下UDP组播
分类专栏: C++

版权声明:本文遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文转自:https://blog.csdn.net/a1173356881/article/details/81608868

最近研究下UDP组播,首先上网看看各种组播的含义,以下是总结的:
    多播,也称为“组播”,将网络中同一业务类型主机进行了逻辑上的分组,进行数据收发的时候其数据仅仅在同一分组中进行,其他的主机没有加入此分组不能收发对应的数据。
    在广域网上广播的时候,其中的交换机和路由器只向需要获取数据的主机复制并转发数据。主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择地复制并传输数据,将数据仅仅传输给组内的主机。多播的这种功能,可以一次将数据发送到多个主机,又能保证不影响其他不需要(未加入组)的主机的其他通 信。
多播的地址是特定的,D类地址用于多播。D类IP地址就是多播IP地址,即224.0.0.0至239.255.255.255之间的IP地址,并被划分为局部连接多播地址、预留多播地址和管理权限多播地址3类:
  
       1、局部多播地址:在224.0.0.0~224.0.0.255之间,这是为路由协议和其他用途保留的地址,路由器并不转发属于此范围的IP包。
  2、预留多播地址:在224.0.1.0~238.255.255.255之间,可用于全球范围(如Internet)或网络协议。
  3、管理权限多播地址:在239.0.0.0~239.255.255.255之间,可供组织内部使用,类似于私有IP地址,不能用于Internet,可限制多播范围。
  多播的程序设计使用setsockopt()函数和getsockopt()函数来实现,组播的选项是IP层的,其选项值和含义参见下表。
                         
getsockopt()/setsockopt()的选项            含 义
IP_MULTICAST_TTL                                 设置多播组数据的TTL值
IP_ADD_MEMBERSHIP                            在指定接口上加入组播组
IP_DROP_MEMBERSHIP                          退出组播组
IP_MULTICAST_IF                                    获取默认接口或设置接口
IP_MULTICAST_LOOP                              禁止组播数据回送

下面是写的实例代码:
client代码
#include <stdio.h>  

#include <winsock2.h>  

#include <ws2tcpip.h>  

#pragma comment(lib, "ws2_32.lib")



int main()

{

int iRet = 0;

WSADATA wsaData;

WSAStartup(MAKEWORD(2, 2), &wsaData);



SOCKET sock = socket(AF_INET,SOCK_DGRAM,0);



int iFlag = 0; // 0-同一台主机 1-夸主机

iRet = setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&iFlag, sizeof(iFlag));

if(iRet != 0){

printf("setsockopt fail:%d", WSAGetLastError());

return -1;

}



sockaddr_in addr;

addr.sin_addr.S_un.S_addr = inet_addr("234.2.2.2");

addr.sin_family = AF_INET;

addr.sin_port = htons(9411);



char strSend[1024] = {0};

static int iIdx = 0;

while(1)  

{    

sprintf_s(strSend, "udp send group data:%d", iIdx++);

iRet = sendto(sock, strSend, strlen(strSend) + 1, 0, (sockaddr*)&addr, sizeof(sockaddr));

if(iRet <= 0){

printf("send fail:%d", WSAGetLastError());

}else{

printf("send data:%s\n", strSend);

}

Sleep(500);

}  



closesocket(sock);

WSACleanup();



return 0;

}

server代码:


#include <stdio.h>  

#include <winsock2.h>  

#include <ws2tcpip.h>  

#pragma comment(lib, "ws2_32.lib")



int main()

{

int iRet = 0;

WSADATA wsaData;

WSAStartup(MAKEWORD(2, 2), &wsaData);



SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);



sockaddr_in addr;

addr.sin_family = AF_INET;

//addr.sin_addr.S_un.S_addr = INADDR_ANY;

addr.sin_addr.S_un.S_addr = inet_addr("192.168.0.104");

addr.sin_port = htons(9411);



bool bOptval = true;

iRet = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptval, sizeof(bOptval));

if(iRet != 0){

printf("setsockopt fail:%d", WSAGetLastError());

return -1;

}



iRet = bind(sock, (sockaddr*)&addr, sizeof(addr));

if(iRet != 0){

printf("bind fail:%d", WSAGetLastError());

return -1;

}

printf("socket:%d bind success\n", sock);



// 加入组播  

ip_mreq multiCast;

//multiCast.imr_interface.S_un.S_addr = INADDR_ANY;

multiCast.imr_interface.S_un.S_addr = inet_addr("192.168.0.104");

multiCast.imr_multiaddr.S_un.S_addr = inet_addr("234.2.2.2");

iRet = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multiCast, sizeof(multiCast));

if(iRet != 0){

printf("setsockopt fail:%d", WSAGetLastError());

return -1;

}



printf("udp group start\n");



int len = sizeof(sockaddr);

char strRecv[1024] = {0};

while(true)  

{    

memset(strRecv, 0, sizeof(strRecv));

iRet = recvfrom(sock, strRecv, sizeof(strRecv) - 1, 0, (sockaddr*)&addr, &len);

if(iRet <= 0){

printf("recvfrom fail:%d", WSAGetLastError());

return -1;

}

printf("recv data:%s\n", strRecv);

}  



closesocket(sock);

WSACleanup();



return 0;

}

程序猿的技术大观园:www.javathinker.net
  Java面向对象编程-->操作符
  JavaWeb开发-->使用Session(Ⅱ)
  JSP与Hibernate开发-->Java应用分层架构及软件模型
  Java网络编程-->安全网络通信
  精通Spring-->Vue简介
  Vue3开发-->绑定表单
  从实战角度解读JVM:类加载机制+JVM调优实战+代码优化!
  我是如何把一个15分钟的程序优化到了10秒的
  深入Java单例模式
  BST 二叉搜索树
  关于新书
  JDBC API中的桥接模式
  java.util.logging.Logger使用详解
  超详细的Java运算符修炼手册(优秀程序员不得不知道的运算技...
  Java设计模式:备忘录模式
  Java设计模式:组合模式
  Java 入门实用代码:从 List列表中 截取子列表
  Java入门实用代码:数组转集合
  Java 入门实用代码:汉诺塔算法
  java Pattern和Matcher详解
  jdbc连接各种数据库代码
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。