Java网络编程----UDP实现单播,组播,广播

文章开头,先来回忆一下

什么是UDP?

UDP 的全称是 User Datagram Protocol,用户数据报协议。它不需要所谓的握手操作,从而加快了通信速度,允许网络上的其他主机在接收方同意通信之前进行数据传输。

UDP 的特点主要有?

UDP 能够支持容忍数据包丢失的带宽密集型应用程序

UDP 具有低延迟的特点 UDP 能够发送大量的数据包

UDP 能够允许 DNS 查找,DNS 是建立在 UDP 之上的应用层协议。

那不得不说一下

什么是TCP?

TCP 的全称是Transmission Control Protocol ,传输控制协议。它能够帮助你确定计算机连接到 Internet 以及它们之间的数据传输。通过三次握手来建立 TCP 连接,三次握手就是用来启动和确认 TCP 连接的过程。一旦连接建立后,就可以发送数据了,当数据传输完成后,会通过关闭虚拟电路来断开连接。

TCP 的主要特点有?

TCP 能够确保连接的建立和数据包的发送

TCP 支持错误重传机制 TCP 支持拥塞控制,能够在网络拥堵的情况下延迟发送 TCP

能够提供错误校验和,甄别有害的数据包。

UDP 和 TCP 的区别?

TCP 是面向连接的协议 。 UDP 是无连接的协议

TCP 在发送数据前先需要建立连接,然后再发送数据 。 UDP 无需建立连接就可以直接发送大量数据

TCP 会按照特定顺序重新排列数据包 。 UDP 数据包没有固定顺序,所有数据包都相互独立

TCP 传输的速度比较慢 。 UDP 的传输会更快 TCP 的头部字节有 20 字节 。 UDP 的头部字节只需要 8 个字节

TCP 是重量级的,在发送任何用户数据之前,TCP需要三次握手建立连接。 UDP 是轻量级的。没有跟踪连接,消息排序等。

TCP 会进行错误校验,并能够进行错误恢复 。 UDP 也会错误检查,但会丢弃错误的数据包

TCP 有发送确认。 UDP 没有发送确认

TCP 会使用握手协议,例如 SYN,SYN-ACK,ACK。 UDP无握手协议

TCP 是可靠的,因为它可以确保将数据传送到路由器。 UDP 中不能保证将数据传送到目标

UDP发送数据

接下进入正题,使用Java语言实现UDP发送数据与接收数据。

1.单播

单播的发送端具体流程

1.准备我们的数据源,如字符串数据,需要将其转为byte数组

2.准备你要传输的ip地址以及端口号

3.使用DatagramPacket进行将以上数据进行包装

4.通过DatagramSocket来发送我们的DatagramPacket

单播的接收端具体流程

1.准备好接收数组,用于接收数据缓冲

2.准备DatagramSocket,需要传入端口号,表示别人将从该端口进行发送数据

3.使用DatagramSocket进行数据接收,结果将返回在DatagramPacket对象中

4.调用DatagramPacket对象方法进行数据处理

发送:

package com.wxy.inetPackage;

import java.io.IOException;
import java.net.*;

public class DatagramSend {
    public static void main(String[] args) throws IOException {
        DatagramSocket datagramSocket = new DatagramSocket();
        String str = "你好啊我是你的好朋友来自UDP";
        byte[] bytes = str.getBytes();
        InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
        int port = 10086;
        DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,inetAddress,port);

        datagramSocket.send(datagramPacket);
        datagramSocket.close();


    }
}

接收:

package com.wxy.inetPackage;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class DatagramReceive {
    public static void main(String[] args) throws IOException {
        DatagramSocket datagramSocket = new DatagramSocket(10086);
        byte[] bytes = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
        datagramSocket.receive(datagramPacket);

        //解析数据
        byte[] data = datagramPacket.getData();
        int length = datagramPacket.getLength();
        InetAddress address = datagramPacket.getAddress();
        int port = datagramPacket.getPort();
        System.out.println("当前收到数据是:" + new String(data,0,length) + ",长度为" + length + ",发送端的地址是" + address + ",端口号是" + port);

        datagramSocket.close();
    }
}

2.组播

这里需要用到一个新的Socket,叫做MulticastSocket,使用它用来发送与接收我们的组播数据。其次需要注意的是,组播最好使用预留的224.0.0.0-224.0.0.255,其它与单播大致相同。

发送

package com.wxy.inetPackage;

import com.wxy.shiyanwu.User;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class MulticastSend {
    public static void main(String[] args) throws IOException {
        MulticastSocket multicastSocket = new MulticastSocket();
        InetAddress inetAddress = InetAddress.getByName("224.0.0.1");
        String msg = "你好这里来自组播--";
        byte[] bytes = msg.getBytes();
        int port = 10000;
        DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,inetAddress,port);
        multicastSocket.send(datagramPacket);
        multicastSocket.close();
    }
}

接收

package com.wxy.inetPackage;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class MultiRec {
    public static void main(String[] args) {

        for (int i = 0;i < 3;i ++) {
            new Thread(()->{

                try (MulticastSocket multicastSocket = new MulticastSocket(10000);){
                    InetAddress inetAddress = InetAddress.getByName("224.0.0.1");
                    multicastSocket.joinGroup(inetAddress);
                    byte[] bytes = new byte[1024];
                    DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
                    multicastSocket.receive(datagramPacket);
                    byte[] data = datagramPacket.getData();
                    System.out.println(Thread.currentThread().getName() + "收到数据:" + new String(data,0,datagramPacket.getLength()) + "hello");
                }catch (IOException e){
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

3.广播

广播更为简单,只需要将单播发送的ip改为广播IP即可,即255.255.255.255,接收就不上代码了,使用广播发送所有局域网上的IP都能接收得到,所以直接使用上方提供的单播接收也是可以接收到的。

package com.wxy.inetPackage;

import java.io.IOException;
import java.net.*;

public class DatagramSend {
    public static void main(String[] args) throws IOException {
        DatagramSocket datagramSocket = new DatagramSocket();
        String str = "你好啊我是你的好朋友来自UDP";
        byte[] bytes = str.getBytes();
        InetAddress inetAddress = InetAddress.getByName("255.255.255.255");
        int port = 10086;
        DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,inetAddress,port);

        datagramSocket.send(datagramPacket);
        datagramSocket.close();


    }
}
相关推荐
顾北川_野4 分钟前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航7 分钟前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
weixin_4426434222 分钟前
推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案
服务器·网络·安全·filelink数据摆渡系统
confiself23 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq041527 分钟前
J2EE平台
java·java-ee
XiaoLeisj34 分钟前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
阑梦清川36 分钟前
JavaEE初阶---网络原理(五)---HTTP协议
网络·http·java-ee
豪宇刘1 小时前
SpringBoot+Shiro权限管理
java·spring boot·spring
Elaine2023911 小时前
02多线程基础知识
java·多线程
gorgor在码农1 小时前
Redis 热key总结
java·redis·热key