udp通信的简单使用

UDP简介

UDP(User Datagram Protocol)是一种非面向连接的提供不可靠的数据包式的数据传输协议。类似于快递运输,运输过程中可能出现丢失。Java中有些类是基于UDP协议来进行网络通讯的,有DatagramPacket、DatagramSocket、MulticastSocket等类

与TCP的区别

TCP是可靠连接传输协议,UDP是不可靠传输协议

  • TCP在传输过程中不会出现丢失数据,一端没收到数据会重发,UDP在传输过程中可能丢失数据
  • TCP是面向连接的,有三次握手四次挥手,UDP无需连接,只需指定IP和端口
  • UDP传输有大小限制,每一个数据报需在64K以内

使用场景

TCP应用场景:当强调数据传输性能让位于数据传输的完整性,可控制性和可靠性

  • Telnet远程登录
  • Ftp文件传输
  • 视频解码(tcp则不会出现跳帧,在网络不太好的情况下延时会比较大)

UDP应用场景:当强调输出性能而非完整性时,如音视频和多媒体的应用

  • ping指令,用来检测网络上某台服务器是否还在提供服务
  • 视频解码(udp会出现跳帧,网络不好的情况下延时非常低,强调实时)

实现流程:

udp通信流程

  • 监听端口
  • 独立线程监听接收
  • 独立线程数据发送

代码结构:

在这里插入图片描述

代码实现:

主要实现:

package com.haoyang.networksdk.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class UdpSdk {

    private DatagramSocket datagramSocket;
    private DatagramPacket sendDatagramPacket,receiveDatagramPacket;
    private static UdpSdk udpSdk;
    private ExecutorService executorService;

    private UdpSdk() {
    }

    public static UdpSdk getInstance(){
        if (udpSdk == null){
            synchronized (UdpSdk.class){
                if (udpSdk == null){
                    udpSdk = new UdpSdk();
                }
            }
        }
        return udpSdk;
    }

    private ExecutorService getExecutorService(){
        if (executorService == null || executorService.isShutdown()){
            executorService = Executors.newFixedThreadPool(4);
        }
        return executorService;
    }

    public void init(int port){
        try {
            datagramSocket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public void sendUdpCommand(byte[] command, String ip, int port){
        getExecutorService().submit(new SendCommandRunnable(command,ip,port));
    }

    public void receiveUdpCommand(UdpCallBack udpCallBack){
        getExecutorService().submit(new ReceiveCommandRunnable(udpCallBack));
    }

    class SendCommandRunnable extends Thread{
        private byte[] command;
        private String ip;
        private int port;
        public SendCommandRunnable(byte[] command, String ip, int port) {
            this.command = command;
            this.ip = ip;
            this.port = port;
        }
        @Override
        public void run() {
            try {
                if (datagramSocket != null) {
                    sendDatagramPacket = new DatagramPacket(command, command.length, InetAddress.getByName(ip), port);
                    datagramSocket.send(sendDatagramPacket);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    class ReceiveCommandRunnable extends Thread{
        private UdpCallBack udpCallBack;
        public ReceiveCommandRunnable(UdpCallBack udpCallBack) {
            this.udpCallBack = udpCallBack;
        }
        @Override
        public void run() {
            while (true) {
                try {
                    if (datagramSocket != null) {
                        byte[] bytes = new byte[1024];
                        receiveDatagramPacket = new DatagramPacket(bytes, bytes.length);
                        datagramSocket.receive(receiveDatagramPacket);
                        udpCallBack.onReceive(receiveDatagramPacket.getData());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

数据接收回调接口:

package com.haoyang.networksdk.udp;

public interface UdpCallBack {
    void onReceive(byte[] bytes);
}

调用:

 UdpSdk.getInstance().init(8888);
        UdpSdk.getInstance().sendUdpCommand(new byte[]{1, 1, 1, 1, 1},"192.168.1.127", 8899);
        UdpSdk.getInstance().receiveUdpCommand(new UdpCallBack() {
            @Override
            public void onReceive(byte[] bytes) {
                Timber.i("udp"+bytes.toString());
            }
        });

测试工具:

为了测试udp服务端是否能够通信,使用sokit.exe测试

在这里插入图片描述

打开后切换到server,输入UDP Addr和Port启动udp,点击TCPListen启动服务,可监听客户端发送的消息,挺好的一个测试工具,推荐大家使用

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值