网络编程(四)UDP通信

UDP

        以数据为中心,非面向连接,不安全数据可能丢失但是效率高,例如短信

涉及到的类

        DatagramSocket 和 DatagramPacket

DatagramSocket

此类表示用来发送和接收数据报包的套接字。

数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。

在 DatagramSocket 上总是启用 UDP 广播发送。为了接收广播包,应该将 DatagramSocket 绑定到通配符地址。在某些实现中,将 DatagramSocket 绑定到一个更加具体的地址时广播包也可以被接收。

扫描二维码关注公众号,回复: 1616689 查看本文章

示例:DatagramSocket s = new DatagramSocket(null); s.bind(new InetSocketAddress(8888)); 这等价于:DatagramSocket s = new DatagramSocket(8888); 两个例子都能创建能够在 UDP 8888 端口上接收广播的 DatagramSocket。

DatagramPacket

此类表示数据报包。

数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。

一个短信通信的过程:

1、客户端

  • 创建客户端 DatagramSocket类 + 指定端口
  • 准备数据 字节数组
  • 打包 DatagramPacket + 服务器地址及端口
  • 发送数据
  • 释放资源

2、服务器端

  • 创建服务器端 DatagramSocket类 + 指定端口
  • 准备接收容器 字节数组 封装DatagramPacket
  • 包 接收数据
  • 分析数据
  • 释放资源

代码实现 

注意:先启动客户端,然后再启动服务端

服务端:

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

//创建服务器端 DatagramSocket类 + 指定端口
DatagramSocket server = new DatagramSocket(8888);
//准备接收容器 字节数组 封装DatagramPacket
byte[] datas = new byte[1024];
DatagramPacket packet = new DatagramPacket(datas,datas.length);
// 接收数据 包
  server.receive(packet);
//分析数据
  byte[] result = packet.getData();
  System.out.println(new String(result,0,result.length));
  //释放资源
  server.close();
}

客户端:

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

//创建客户端DatagramSocket类 + 指定端口
DatagramSocket client = new DatagramSocket(6666);
//准备数据,字节数组
String str = "udp数据连接测试";
byte[] source = str.getBytes();
//打包 DatagramPacket + 指定服务器地址及端口
DatagramPacket packet = new DatagramPacket(source,0,source.length,
new InetSocketAddress("localhost",8888));
//发送数据
client.send(packet);
//释放资源
client.close();

}

输出:udp数据连接测试


服务器端先启动后,再启动客户端,就可以看到 客户端输入的"udp数据连接测试" 的数据输出

是数据去找服务器,而不是连接的时候去找服务器,所以是非面向连接的

如果不启动服务器,直接启动客户端,不会报错,所以非面向连接是不安全的


发送和接收的数据类型为double

代码实现如下:

客户端:

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

//创建客户端DatagramSocket类 + 指定端口
DatagramSocket client = new DatagramSocket(6666);
//准备数据,字节数组
double num = 10.23;
byte[] source = convert(num);
//打包 DatagramPacket + 服务器地址及端口
DatagramPacket packet = new DatagramPacket(source,0,source.length,
new InetSocketAddress("localhost",8888));
//发送数据
client.send(packet);
//释放资源
client.close();
}

public static byte[] convert(double num) throws IOException{

byte[] data = null;

//利用流将double转为byte

//此类实现了一个输出流,其中的数据被写入一个 byte 数组
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中
DataOutputStream dos = new DataOutputStream(bos);
dos.writeDouble(num);
dos.flush();
data = bos.toByteArray();
bos.close();
return data;
}


服务器端:

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

//创建服务器端 DatagramSocket类 + 指定端口
DatagramSocket server = new DatagramSocket(8888);
//准备接收容器 字节数组 封装DatagramPacket
byte[] datas = new byte[1024];
DatagramPacket packet = new DatagramPacket(datas,datas.length);
// 接收数据 包
  server.receive(packet);
//分析数据
  byte[] result = packet.getData();
  double res = convert(result);
  System.out.println(res);
  //释放资源
  server.close();
}

public static double convert(byte[] data) throws IOException{
                //数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
double num = dis.readDouble();
dis.close();
return num;
}

输出:10.23


自学笔记,多有不足!!!





猜你喜欢

转载自blog.csdn.net/kermit_father/article/details/80716550