java单播多播socket_广播(broadcast),组播(multicast),单播(unicast)的Java实现

## IP地址

在IPv4中,一共有五类IP地址

* A类地址:网络号占1个字节。网络号的第一位固定为0。

* B类地址:网络号占2个字节。网络号的前两位固定为10。

* C类地址:网络号占3个字节。网络号的前三位固定位110。

* D类地址:前四位是1110,用于多播(multicast),即一对多通信。

* E类地址:前四位是1111,保留为以后使用。

其中,D类地址是从224.0.0.0到239.255.255.255这个范围的。这类地址的主要做用就是用作组播(又叫做多播)。

而ABC类地址是单播地址。

广播地址:主机位全部是1的地址都是广播地址,即``。网络位和主机位全都是1的是本地广播地址,即``,IPV4:255.255.255.255。

## 单播

单播就是一对一通信,我们常用的就是TCP协议,在Java中的体现就是Socket和ServerSocket。有人可能会问,那UDP协议呢?其实UDP协议即可以用来做单播又可以用来做多播和广播。Java中,处理UDP对应的是DatagramSocket。

下面我们分别使用TCP和UDP实现一个服务端客户端。

### 基于TCP的实现

TCP服务端:

服务端监听本地端口9999,然后等待客户端输入,将客户端的输入原样输出给客户端。

``` java

/**

* Date: 2016年1月6日 下午1:16:57

* TCP服务端,监听端口,等待连接,然后将客户端的输入的内容原样返回给客户端

*/

public class TCPUnicastServer {

public static void main(String[] args) throws Exception {

ServerSocket serverSocket = null;

try {

// 服务端,绑定到端口9999

serverSocket = new ServerSocket(9999);

while (true) {

final Socket clientSocket = serverSocket.accept();

// 启动一个线程,处理客户端连接

new Thread() {

@Override

public void run() {

try {

BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

PrintWriter writer = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

// 监听客户端的输入

while (true) {

String requestData = reader.readLine();

if (requestData == null) {

break;

}

System.out.println("server received:" + requestData);

// 将客户端的输入原样返回给客户端

writer.println(requestData);

writer.flush();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}.start();

}

} finally {

if (serverSocket != null) {

try {

serverSocket.close();

} catch (IOException e) {

}

}

}

}

}

```

TCP客户端:

客户端负责与客户端建立连接,并向服务端发送数据,同时接受服务端返回的结果。

``` java

public static void main(String[] args) throws Exception {

// 向服务端创建连接

Socket socket = new Socket("127.0.0.1", 9999);

BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

// 发送数据

writer.println("Hello,i am client");

writer.flush();

// 等待服务端响应

while (true) {

String serverData = reader.readLine();

if (serverData == null) {

break;

}

System.out.println("client received:" + serverData);

}

socket.close();

}

```

TCP的实现比较特殊,Socket分为服务端Socket(ServerSocket)和客户端Socket(Socket)。

### 基于UDP的实现

Java中UDP对应的Socket只有一个DatagramSocket,不区分客户端与服务端(想想也是)。

发送数据的一端:

``` java

public static void main(String[] args) throws Exception {

DatagramSocket serverSocket = new DatagramSocket();

// 发送的目的地址和端口

InetAddress destination = InetAddress.getByName("127.0.0.1");

for (int i = 0; i < 10; i++) {

byte[] buf = "Hello client".getBytes();

DatagramPacket packet = new DatagramPacket(buf, buf.length, destination, 9999);

serverSocket.send(packet);

TimeUnit.SECONDS.sleep(5);

}

serverSocket.close();

}

```

接收数据的一端:

``` java

public static void main(String[] args) throws Exception {

DatagramSocket clientSocket = new DatagramSocket(9999);

while (true) {

DatagramPacket packet = new DatagramPacket(new byte[256], 256);

clientSocket.receive(packet);

System.out.println(new String(packet.getData()).trim());

}

}

```

说明:

1. 发送端和接收端都使用DatagramSocket

2. 发送端发送的时候指定的地址是一个单播地址

3. 发送和接收数据使用的是DatagramPacket

## 多播

多播就是一对多通信,即从一台机器发送数据到多台机器。在Java里的体现就是MulticastSocket,MulticastSocket是DatagramSocket的子类。

很多人喜欢将多播称作组播,是因为多播不同于广播,广播是向所有机器发送数据,而多播是针对某一组机器发送数据。下面我们来看一下多播的实现。

发送数据的一端:

``` java

public static void main(String[] args) throws Exception {

// 指定组播要发送的组

InetAddress group = InetAddress.getByName("224.0.0.3");

// 创建MulticastSocket,它是DatagramSocket的子类

MulticastSocket socket = new MulticastSocket();

for (int i = 0; i < 10; i++) {

String data = "hello client";

byte[] bytes = data.getBytes();

// 将数据发送到对应组的对应端口

socket.send(new DatagramPacket(bytes, bytes.length, group, 9999));

TimeUnit.SECONDS.sleep(5);

}

socket.close();

}

```

接收数据的一端:

``` java

public static void main(String[] args) throws IOException {

// 多播客户端监听相应的端口

MulticastSocket clientSocket = new MulticastSocket(9999);

// 客户端将自己加入到指定的多播组中,这样就能收到来自这个组的消息

InetAddress group = InetAddress.getByName("224.0.0.3");

clientSocket.joinGroup(group);

byte[] buf = new byte[256];

while (true) {

// 读取数据

DatagramPacket msgPacket = new DatagramPacket(buf, buf.length);

clientSocket.receive(msgPacket);

String msg = new String(msgPacket.getData());

System.out.println("Socket 1 received msg: " + msg.trim());

}

//离开组

//clientSocket.leaveGroup(group);

}

```

说明:

1. 多播发送端和接收端使用的都是MulticastSocket,它是DatagramSocket的一个子类,其实在底层,多播也是基于UDP的。

2. 客户端需要加入到对应的group中,才可以接收到服务端的消息:`clientSocket.joinGroup(group);`

## 广播

广播分组的目标IP地址的主机部分全为1,这意味着本地网络(广播域)中的所有主机都将接收并查看该分组。诸如ARP和DHCP等很多网络协议都使用广播。

例如:

1. C类网络192.168.1.0的默认子网掩码为255.255.255.0,其广播地址为192.168.1.255,其主机部分为十进制数255或二进制数11111111(全为1)。

2. B类网络172.16.0.0的默认子网掩码为255.255.0.0,其广播地址为172.16.255.255。

3. A类网络10.0.0.0的默认子网掩码为255.0.0.0,其广播地址为10.255.255.255。

在java中,广播也是借助DatagramSocket实现的。

消息发送方

``` java

public static void main(String[] args) throws Exception {

DatagramSocket serverSocket = new DatagramSocket();

// 发送的目的地址和端口

InetAddress destination = InetAddress.getByName("255.255.255.255");

for (int i = 0; i < 10; i++) {

byte[] buf = "Hello client".getBytes();

DatagramPacket packet = new DatagramPacket(buf, buf.length, destination, 9999);

serverSocket.send(packet);

TimeUnit.SECONDS.sleep(5);

}

serverSocket.close();

}

```

注意:发送的地址必须是广播地址。

消息接收方

``` java

public static void main(String[] args) throws Exception {

DatagramSocket clientSocket = new DatagramSocket(9999);

while (true) {

DatagramPacket packet = new DatagramPacket(new byte[256], 256);

clientSocket.receive(packet);

System.out.println(new String(packet.getData()).trim());

}

}

```

其实仔细观察一下你会发现,在前面的UDP实现单播的时候的代码与广播的代码基本是一样的,区别就在于单播的时候目的端的地址必须是单播地址,而广播的时候,目的端的地址必须是广播地址。

## 单播,组播,广播都有哪些应用场景?

1. 单播:点对点通信,最常用的就是TCP协议。

2. 组播:一对多通信,视频教学:多个学生连接到同一个服务端。

3. 广播:一对多通信,DHCP动态分配IP地址的时候,客户机器就是通过发送一个广播信息,只有DHCP服务器才会对这个广播信息进行响应。

## 总结

1. IPv4地址分为五类,其中ABC三类都是单播地址,D类是多播地址,地址范围为224.0.0.0到239.255.255.255。

2. 广播地址:地址位都为1。网络位和地址位都为1的(255.255.255.255)为本地广播地址。

3. 广播和多播都是通过UDP协议实现的,在Java中广播是借助DatagramSocket实现,多播是MulticastSocket,后者是前者的子类。

## 扩展阅读

1. http://www.nakov.com/inetjava/lectures/part-1-sockets/InetJava-1.5-UDP-and-Multicast-Sockets.html

2. http://book.51cto.com/art/200904/120471.htm

3. http://colobu.com/2014/10/21/udp-and-unicast-multicast-broadcast-anycast/(这篇文章讲解的非常好)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个强大的跨平台应用程序框架,可以用于实现单播组播广播通信。 对于单播通信,Qt可以利用TCP/IP协议来实现。通过建立一个TCP连接,可以在不同的主机间进行点对点通信。在Qt中,可以使用QTcpSocket和QTcpServer来创建一个TCP套接字和服务器,分别用于发送和接收单播消息。通过调用套接字的connectToHost函数连接到目标主机,并通过write函数向目标主机发送消息。目标主机接收到消息后,可以使用readyRead信号进行处理。 对于组播通信,Qt可以利用UDP协议来实现。通过建立一个UDP套接字,可以在一个组内的多个主机之间进行通信。在Qt中,可以使用QUdpSocket类来实现UDP通信。通过创建一个QUdpSocket对象,并使用bind函数将其绑定到一个地址和端口上。然后可以设置套接字的MulticastTtl属性,以确定组播消息能够传播的跳数。使用writeDatagram函数向组内的所有主机发送消息。 对于广播通信,Qt同样可以使用UDP协议来实现广播是一种特殊的组播,消息将会发送到同一网络中的所有主机。广播实现组播类似,只需要将QUdpSocket的套接字选项设置为Broadcast,并使用writeDatagram函数将消息发送到广播地址。 通过使用Qt的网络模块,可以方便地实现单播组播广播通信,使得应用程序可以在不同的网络环境中进行可靠的数据传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值