1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Java 基于UDP 实现单播 组播 广播 Socket 编程

Java 基于UDP 实现单播 组播 广播 Socket 编程

时间:2024-01-02 02:47:05

相关推荐

Java 基于UDP 实现单播 组播 广播 Socket 编程

UDP信息传递的方式

单播(unicast):

是指封包在计算机网络的传输中,目的地址为单一目标的一种传输方式。它是现今网络应用最为广泛,通常所使用的网络协议或服务大多采用单播传输,例如一切基于TCP的协议。

组播(multicast):

也叫多播, 多点广播或群播。 指把信息同时传递给一组目的地址。它使用策略是最高效的,因为消息在每条网络链路上只需传递一次,而且只有在链路分叉的时候,消息才会被复制。

多播组通过 D 类 IP 地址和标准 UDP 端口号指定。D 类 IP 地址在 224.0.0.0 和 239.255.255.255 的范围内(包括两者)。地址 224.0.0.0 被保留,不应使用。

广播(broadcast):

是指封包在计算机网络中传输时,目的地址为网络中所有设备的一种传输方式。实际上,这里所说的“所有设备”也是限定在一个范围之中,称为“广播域”。

详细介绍(来自维基百科)

单播:

每次只有两个实体相互通信,发送端和接收端都是唯一确定的。

在IPv4网络中,0.0.0.0到223.255.255.255属于单播地址。

你对小月月喊“小月月”,那么只有小月月回过头来答应你。

组播:

“组播”这个词通常用来指代IP组播。IP组播是一种通过使用一个组播地址将数据在同一时间以高效的方式发往处于TCP/IP网络上的多个接收者的协议。此外,它还常用来与RTP等音视频协议相结合。

互联网架构师戴夫·克拉克是这样描述IP组播的:“你把数据包从一头放进去,网络就会试图将它们传递到想要得到它们的人那里。”

组播报文的目的地址使用D类IP地址, D类地址不能出现在IP报文的源IP地址字段。

你在大街上大喊一声“美女”, 会有一群女性回头看你。

组播地址(参考 iana)

组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。

224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;224.0.1.0~224.0.1.255是公用组播地址,Internetwork Control Block;224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。

永久的组播地址:

224.0.0.0 基准地址(保留)224.0.0.1 所有主机的地址 (包括所有路由器地址)224.0.0.2 所有组播路由器的地址224.0.0.3 不分配224.0.0.4 dvmrp路由器224.0.0.5 所有ospf路由器224.0.0.6 ospf DR/BDR224.0.0.7 st路由器224.0.0.8 st主机224.0.0.9 rip-2路由器224.0.0.10 Eigrp路由器224.0.0.11 活动代理224.0.0.12 dhcp 服务器/中继代理224.0.0.13 所有pim路由器224.0.0.14 rsvp封装224.0.0.15 所有cbt路由器224.0.0.16 指定sbm224.0.0.17 所有sbms224.0.0.18 vrrp

以太网传输单播ip报文的时候,目的mac地址使用的是接收者的mac地址。但是在传输组播报文时,传输目的不再是一个具体的接收者,而是一个成员不确定的组,所以使用的是组播mac地址。组播mac地址是和组播ip地址对应的。iana(internet assigned number authority)规定,组播mac地址的高24bit为0x01005e,mac 地址的低23bit为组播ip地址的低23bit。

由于ip组播地址的后28位中只有23位被映射到mac地址,这样就会有32个ip组播地址映射到同一mac地址上。

广播:

并非所有的计算机网络都支持广播,例如X.25网络和帧中继都不支持广播,而且也没有在“整个互联网范围中”的广播。IPv6亦不支持广播,广播相应的功能由组播代替。

通常,广播都是限制在局域网中的,比如以太网或令牌环网络。因为广播在局域网中造成的影响远比在广域网中小得多。

以太网和IPv4网都用全1的地址表示广播,分别是ff:ff:ff:ff:ff:ff和255.255.255.255。

令牌环网络使用IEEE 802.2控制域中的一个特殊值来表示广播。

你在公司大喊一声“放假了”, 全部同事都会响应,大叫爽死了。

Java 基于 UDP 的 Socket编程

单播:

ChatDemo.java

packageudp;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;.DatagramPacket;.DatagramSocket;.InetAddress;.SocketException;/*****编写一个聊天的工具*有收数据部分,和发数据部分*这两个不部分同时执行*就需要多线程技术*一个线程控制收,一个线程控制发**因为收和发动作是不一致的,所以要定义两个方法*而且这两个方法要封装到不同的类中**@author言曌*@date/12/6下午8:25*/classSendimplementsRunnable{privateDatagramSocketsocket;publicSend(DatagramSocketsocket){this.socket=socket;}@Overridepublicvoidrun(){try{BufferedReaderbufferedReader=newBufferedReader(newInputStreamReader(System.in));Stringline=null;while((line=bufferedReader.readLine())!=null){byte[]buff=line.getBytes();DatagramPacketpacket=newDatagramPacket(buff,buff.length,InetAddress.getByName("192.168.168.106"),10001);socket.send(packet);if("bye".equals(line)){break;}}socket.close();}catch(IOExceptione){e.printStackTrace();}}}classReceimplementsRunnable{privateDatagramSocketsocket;publicRece(DatagramSocketsocket){this.socket=socket;}@Overridepublicvoidrun(){try{while(true){byte[]buff=newbyte[1024];DatagramPacketpacket=newDatagramPacket(buff,buff.length);socket.receive(packet);Stringip=packet.getAddress().getHostAddress();Stringdata=newString(packet.getData(),0,packet.getLength());if("bye".equals(data)){System.out.println(ip+"已经离开了");continue;}System.out.println(ip+"说"+data);}}catch(IOExceptione){e.printStackTrace();}}}publicclassChatDemo{/***可以持续发送到192.168.168.106:10001*发送到接受者的10001端口,接受者需要在10001端口接受*/publicstaticvoidmain(Stringargs[])throwsSocketException{DatagramSocketsendSocket=newDatagramSocket();DatagramSocketreveSocket=newDatagramSocket(10001);newThread(newSend(sendSocket)).start();newThread(newRece(reveSocket)).start();}}

说明

我这里有两台电脑

一台 ip:192.168.168.107 Mac

一台电脑:192.168.168.106 Windows

上面的代码是 Mac 的代码,即192.168.168.107 不断给192.168.168.106 的端口10001发送数据

192.168.168.106 在 10001接收

效果图

Mac 端的 IDEA 控制台发送数据并回车

Windows 端的 IDEA 控制台接收数据

组播

ChatDemo2.java

packageudp;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;.*;/*****编写一个聊天的工具*有收数据部分,和发数据部分*这两个不部分同时执行*就需要多线程技术*一个线程控制收,一个线程控制发**因为收和发动作是不一致的,所以要定义两个方法*而且这两个方法要封装到不同的类中**@author言曌*@date/12/6下午8:25*/classSend2implementsRunnable{privateMulticastSocketsocket;publicSend2(MulticastSocketsocket){this.socket=socket;}@Overridepublicvoidrun(){try{BufferedReaderreader=newBufferedReader(newInputStreamReader(System.in));InetAddressgroup=InetAddress.getByName("228.5.6.7");socket.joinGroup(group);Stringline=null;while((line=reader.readLine())!=null){byte[]buff=line.getBytes();DatagramPacketpacket=newDatagramPacket(buff,buff.length,group,6789);socket.send(packet);if("bey".equals(line)){break;}}socket.close();}catch(IOExceptione){thrownewRuntimeException("发送端失败");}}}classRece2implementsRunnable{privateMulticastSocketsocket;publicRece2(MulticastSocketsocket){this.socket=socket;}@Overridepublicvoidrun(){try{byte[]buff=newbyte[1024];InetAddressgroup=InetAddress.getByName("228.5.6.7");socket.joinGroup(group);while(true){DatagramPacketpacket=newDatagramPacket(buff,buff.length);socket.receive(packet);Stringdata=newString(packet.getData(),0,packet.getLength());Stringip=packet.getAddress().getHostAddress();if("bye".equals(data)){System.out.println(ip+"离开了");continue;}System.out.println("ip:"+ip+"说:"+data);}}catch(IOExceptione){thrownewRuntimeException("接受端失败");}}}publicclassChatDemo2{publicstaticvoidmain(Stringargs[])throwsIOException{MulticastSocketsendSocket=newMulticastSocket();MulticastSocketreceSocket=newMulticastSocket(6789);newThread(newSend2(sendSocket)).start();newThread(newRece2(receSocket)).start();}}

说明

还是两天机器,都运行上面的代码。都加入一个 ip 为 228.5.6.7 的组,在 6789 端口接受发数据。

效果图

Mac 端的 IDEA 控制台

Windows 端的 IDEA 控制台

广播

ChatDemo3.java

packageudp;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;.DatagramPacket;.DatagramSocket;.InetAddress;.SocketException;/*****编写一个聊天的工具*有收数据部分,和发数据部分*这两个不部分同时执行*就需要多线程技术*一个线程控制收,一个线程控制发**因为收和发动作是不一致的,所以要定义两个方法*而且这两个方法要封装到不同的类中**@author言曌*@date/12/6下午8:25*/classSend3implementsRunnable{privateDatagramSocketsocket;publicSend3(DatagramSocketsocket){this.socket=socket;}@Overridepublicvoidrun(){try{BufferedReaderbufferedReader=newBufferedReader(newInputStreamReader(System.in));Stringline=null;while((line=bufferedReader.readLine())!=null){byte[]buff=line.getBytes();DatagramPacketpacket=newDatagramPacket(buff,buff.length,InetAddress.getByName("192.168.168.255"),10001);socket.send(packet);if("bye".equals(line)){break;}}socket.close();}catch(IOExceptione){e.printStackTrace();}}}classRece3implementsRunnable{privateDatagramSocketsocket;publicRece3(DatagramSocketsocket){this.socket=socket;}@Overridepublicvoidrun(){try{while(true){byte[]buff=newbyte[1024];DatagramPacketpacket=newDatagramPacket(buff,buff.length);socket.receive(packet);Stringip=packet.getAddress().getHostAddress();Stringdata=newString(packet.getData(),0,packet.getLength());if("bye".equals(data)){System.out.println(ip+"离开了");}System.out.println(ip+"说"+data);}}catch(IOExceptione){e.printStackTrace();}}}publicclassChatDemo3{publicstaticvoidmain(Stringargs[])throwsSocketException{DatagramSocketsendSocket=newDatagramSocket();DatagramSocketreveSocket=newDatagramSocket(10001);newThread(newSend3(sendSocket)).start();newThread(newRece3(reveSocket)).start();}}

说明

广播比较好理解,我这里的局域网网络地址是 192.168.168.0

所以 ip 为 192.168.168.1 - 192.168.168.254 是一个本局域网内的有效 ip 地址

192.168.168.255 被称为广播地址,只要给广播地址发消息,该局域网内的所有人都能收到。

运行结果

Mac 版 IDEA 的控制台

Windows 版 IDEA 的控制台

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。