JAVAEE—实现一个UDP通信的demo

news/2024/5/18 13:17:16 标签: java-ee, udp

文章目录

  • UDP的特点
    • 无连接的
    • 不可靠性
    • 面向报文
    • 阻塞控制
  • 实现UDP通信需要的类和方法
    • DatagramSocket API
    • DatagramPacket API
      • 构造方法
      • DatagramPacket 常用方法
    • InetSocketAddress API
  • 实现UDP通讯的代码
    • UDP 服务器
    • UDP客户端

UDP的特点

无连接的

首先UDP是无连接的,什么是无连接的呢?无连接的意思就是在发送消息的过程中发消息的一方和收消息的一方都不会保存对方的信息。因此我们说他是无连接的,既然是无连接的那么每一次我们发送的消息其实这个信息中不止包含我们想要发送的消息,还包含了对方的IP地址和端口号以及自己的IP地址和端口号。因此就涉及到了另一个特性那就是面向报文传输

不可靠性

不可靠性,为什么说UDP传输时不可靠的呢?这要跟他的传输方式有关因为UDP的传输时尽自己最大能力的传输消息因此它并不保证这个消息能够准确并且完整的传输到对方的手中因此我们说他是不可靠的。

面向报文

面向报文传输。这里跟我们的无连接性其实是有关系的,由于UDP是没有连接的即不会保存通信双方的信息,因此每一次的发送都需要我们将要发送的数据以及发送方的IP地址端口号以及接受方的IP地址端口号进行打包。

阻塞控制

UDP没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。很多的实时应用(如IP电话、实时视频会议等)要去源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太多的时延。UDP正好符合这种要求。

实现UDP通信需要的类和方法

DatagramSocket API

DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。
DatagramSocket 构造方法

方法签名方法使用
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端)
DatagramSocket(int port)创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端)

DatagramSocket 方法

方法签名方法使用
void receive(DatagramPacket p)从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
void send(DatagramPacketp)从此套接字发送数据报包(不会阻塞等待,直接发送)
void close()关闭此数据报套接字

DatagramPacket API

DatagramPacket 类是用来保存UDP通讯中发送和接受的数据报

构造方法

方法名称方法说明
DatagramPacket(byte[]buf, int length)构造一个DatagramPacket 对象并且内部传入一个字节数组,我们要接受的信息全部都存入到这个字节数组中,接受的内容存储在第一个参数buf中接受的指定长度为第二个参数
DatagramPacket(byte[]buf, int offset, int length,SocketAddress address)构造一个DatagramPacket 对象用来发送数据发送的数据内容存储在第一个参数buf中发送的数据是字节长度存储到第二个和第三个参数中,最后一个参数address用来存储目标的IP地址和端口号

DatagramPacket 常用方法

方法签名方法说明
InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int getPort()从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号
byte[] getData()获取数据报中的数据

构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创
建。

InetSocketAddress API

InetSocketAddress ( SocketAddress 的子类 )构造方法:

方法签名方法说明
InetSocketAddress(InetAddress addr, int port)创建一个Socket地址,包含IP地址和端口号

实现UDP通讯的代码

UDP 服务器

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
class UDPserver{
    private DatagramSocket socket=null;
    public UDPserver(int port) throws SocketException {
        socket=new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器正常启动");
        while(true){
            //接收请求
            DatagramPacket requestPacket =new DatagramPacket(new byte[1024],1024);
            socket.receive(requestPacket);
            String reques=new String(requestPacket.getData(),0,requestPacket.getLength());
            //创建回应信息
            String Response=po(reques);
            DatagramPacket responsePacket=new DatagramPacket(Response.getBytes(),0,
                    Response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);
            System.out.printf("[%s,%s,%s,%d]:%s",requestPacket.getAddress(),"发送到",responsePacket.getAddress(),requestPacket.getPort(),Response);
        }
    }
    public String po(String s){
        return s;
    }
}

public class Udpsever {
    public static void main(String[] args) throws IOException {
        UDPserver udPserver=new UDPserver(9090);
        udPserver.start();
    }
}
 

UDP客户端

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

class UDPclient{
    private DatagramSocket datagramSocket=null;
    private String IP;
    private int Port;
    public UDPclient(String Ip,int port) throws SocketException {
        IP=new String(Ip);
        Port=port;
        datagramSocket=new DatagramSocket();
    }
    public void start() throws IOException {
        while(true){
            System.out.print("请输入你的请求->");
            Scanner scanner=new Scanner(System.in);
            String reques=scanner.nextLine();
            DatagramPacket requesgramPacket=new DatagramPacket(reques.getBytes(), reques.getBytes().length,InetAddress.getByName(IP),Port);
            DatagramPacket responsegramPacket=new DatagramPacket(new byte[1024],1024);
            datagramSocket.send(requesgramPacket);
            datagramSocket.receive(responsegramPacket);
            String responce=new String(responsegramPacket.getData(),0,responsegramPacket.getLength());
            System.out.println("response:"+responce);
        }
    }
}
public class Main {
    public static void main(String[] args) throws IOException {
        UDPclient udPclient=new UDPclient("127.0.0.1",9090);
        udPclient.start();
    }
}

http://www.niftyadmin.cn/n/5480908.html

相关文章

UG NX二次开发(C#)-使用UG NX的开发模板创建项目失败的原因和解决方案

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、可能的原因与解决方案2.1 Visual studio安装不完整2.2 解决方案2.2.1 对于 .net 桌面开发2.2.2 使用C++的桌面开发2.2.3 通用Windows平台开发2.2.4 visual studio扩展开发2.2.5 单个组件…

服务器中文字体问题

首先,确保fc-list、fc-cache命令可用,如果该命令不存在,需要安装该命令:https://command-not-found.com/fc-list fc-list 输出: /usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:styleBold /us…

wpf viewmodel和界面双向通知

通知模型(Model)或视图模型(ViewModel) 这两个有什么区别?分别给我代码例子 在MVVM(Model-View-ViewModel)架构中,Model和ViewModel扮演不同的角色: Model表示应用程序的数据域&am…

sqlmap一些常用命令

仅供交流学习使用,请勿用于非法用途 1)检测url存在漏洞情况:python sqlmap.py -u "http://192.168.88.128/sqli-labs-master/Less-1/?id1" 2)获取所有数据库名称:python sqlmap.py -u "http://192.168…

腾讯云云原生数据库TDSQL-C mysql 以及项目怎么接入

要接入腾讯云的云原生数据库TDSQL-C的MySQL版本,并将它用于你的项目中,你需要按照以下步骤进行: 创建TDSQL-C的MySQL数据库实例: 登录腾讯云控制台。在产品搜索框中搜索TDSQL-C,然后选择它。在TDSQL-C的产品页面上&…

Docker- Redis

博文目录 文章目录 说明前置命令 说明 Docker Hub Redis 数据卷数据卷印射在容器内的路径redis/data 容器内的路径说明/data数据目录/data/redis.conf配置文件 前置 在 GitHub 找一份 redis.conf 配置文件, 放到卷 redis 中, 按需修改 # bind 127.0.0.1 # 解除只允许环回地…

鸿蒙实战开发-如何实现标准化数据定义与描述的功能。

介绍 本示例主要使用ohos.data.uniformTypeDescriptor 展示了标准化数据定义与描述的功能,在新增预置媒体文件后,对媒体文件的utd标准类型获取、utd类型归属类型查询、获取文件对应的utd类型的默认图标、支持自定义数据类型等功能。 实现过程中还使用到…

【Hello算法】 > 第 2 关 >数据结构 之 数组与链表

数据结构 之 数组与链表 1:Understanding data structures !——了解数据结构——1.1:Classification-分类-1.2:Type-类型- 2:Arrays are the bricks that make up the wall of data structures *——数组是组成数据结…