8.9 UDP编程:基本类型数据传输与对象数据传输

UDP编程:基本类型数据传输与对象数据传输

基本类型数据传输

code
接收端

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * 接收端:测试基本数据类型的接收
 * 1. 使用DatagramSocket 创建接收端,指定端口
 * 2. 准备容器,封装成DatagramPacket包裹
 * 3. 阻塞式接收包裹receive(DatagramPacket p)
 * 4. 分析数据 , 将字节数组还原位为原类型数据
 * 		byte[] getData();
 * 		int getLength();
 * 5. 释放资源 
 * @author dxt
 *
 */
public class UdpTypeServer {
	public static void main(String[] args) throws IOException{
		System.out.println("服务器端启动中......");
		//1.
		DatagramSocket server = new DatagramSocket(9999);
		//2. 
		byte[] container = new byte[1024 * 60];
		DatagramPacket packet = new DatagramPacket(container, 0, container.length); 
		//3. 
		server.receive(packet);
		//4. 分析数据,获取字节流,将其解析成对应的基本数据类型
		byte[] datas = packet.getData();
		int len = packet.getLength();
		DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
		//将数据按对应顺序写出, 对应读入
		String msg = dis.readUTF();
		int num = dis.readInt();
		boolean flag = dis.readBoolean();
		char ch = dis.readChar();
		//打印
		System.out.println(msg);
		System.out.println(num);
		System.out.println(flag);
		System.out.println(ch);
		//5. 
		server.close(); 
	}
}

发送端

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
 * 发送端(测试基本类型数据的发送)
 * 1. 使用DatagramSocket 创建发送端,要制定端口
 * 2. 将基本类型数据 转为字节数组
 * 3. 封装成 DatagramPacket包裹,指定目的地
 * 4. 发送包裹send(DatagramPacket p)
 * 5. 释放资源
 * @author dxt
 *
 */
public class UdpTypeClient {
	public static void main(String[] args) throws IOException{
		System.out.println("客户端启动中......");
		//1. 
		DatagramSocket client = new DatagramSocket(8888);
		//2. 使用IO流将基本数据类型转为字节流
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(baos);
		dos.writeUTF("有内鬼,终止交易");
		dos.writeInt(1024);
		dos.writeBoolean(false);
		dos.writeChar('A');
		dos.flush();
		
		byte[] datas = baos.toByteArray();	//获取基本类型的字节数组
		//3.
		DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("127.0.0.1", 9999));
		//4. 
		client.send(packet);
		//5. 
		client.close();
	}
}

对象数据传输

code
接收端

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Date;

/**
 * 接收端:测试传输对象数据,引用类型
 * 1. 使用DatagramSocket 创建接收端,指定端口
 * 2. 准备容器,封装成DatagramPacket包裹
 * 3. 阻塞式接收包裹receive(DatagramPacket p)
 * 4. 分析数据 , 将字节数组还原位为原类型数据
 * 		byte[] getData();
 * 		int getLength();
 * 5. 释放资源 
 * @author dxt
 *
 */
public class UdpObjServer {
	public static void main(String[] args) throws IOException, ClassNotFoundException{
		System.out.println("服务器端启动中......");
		//1.
		DatagramSocket server = new DatagramSocket(9999);
		//2. 
		byte[] container = new byte[1024 * 60];
		DatagramPacket packet = new DatagramPacket(container, 0, container.length); 
		//3. 
		server.receive(packet);
		//4. 分析数据,获取字节流,将其解析成对应的基本数据类型
		byte[] datas = packet.getData();
		int len = packet.getLength();
		ByteArrayInputStream bais = new ByteArrayInputStream(datas);
		BufferedInputStream bis = new BufferedInputStream(bais);
		ObjectInputStream ois = new ObjectInputStream(bis);
		
		Object msg2 = ois.readObject();
		if(msg2 instanceof String){	//类型转换,在转换前先判断是否属于
			String str = (String)msg2;
			System.out.println(str);
		}
		Object d = ois.readObject();
		if(d instanceof Date){
			Date date = (Date)d;
			System.out.println(date);
		}
		
		Object employee = ois.readObject();
		if(employee instanceof Employee){
			Employee e = (Employee)employee;
			System.out.println(e.getName() + "--" + e.getSalary());
		}
		ois.close();
		//5. 
		server.close(); 
	}
}

发送端

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Date;


/**
 * 发送端:测试传输对象数据,引用类型
 * 1. 使用DatagramSocket 创建发送端,要制定端口
 * 2. 将基本类型数据 转为字节数组
 * 3. 封装成 DatagramPacket包裹,指定目的地
 * 4. 发送包裹send(DatagramPacket p)
 * 5. 释放资源
 * @author dxt
 *
 */
public class UdpObjClient {
	public static void main(String[] args) throws IOException{
		System.out.println("客户端启动中......");
		//1. 
		DatagramSocket client = new DatagramSocket(8888);
		//2. 使用IO流将基本数据类型转为字节流
		//写出, 节点流使用的是字节数组流
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		BufferedOutputStream bos = new BufferedOutputStream(baos);
		ObjectOutputStream oos = new ObjectOutputStream(bos);
		
		//对象
		oos.writeObject("无所畏惧");
		oos.writeObject(new Date());
		//自定义对象
		Employee emp = new Employee("dxt", 10.0);
		oos.writeObject(emp);
		oos.flush();
		byte[] datas = baos.toByteArray();
		
		//3.
		DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("127.0.0.1", 9999));
		//4. 
		client.send(packet);
		//5. 
		client.close();
	}
}

class Employee implements Serializable{
	private transient String name;		//加transiet 则此数据不会被序列化
	private double salary;
	
	public Employee(){}
	public Employee(String name, double s){
		this.name = name;
		this.salary = s;
	}
	public String getName(){
		return this.name;
	}
	public void setName(String name){
		this.name = name;
	}
	public double getSalary(){
		return this.salary;
	}
	public void setSalary(double s){
		this.salary = s;
	}
}

文件传输

接收端
code

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

public class UdpFileServer {
	public static void main(String[] args) throws IOException{
		System.out.println("接收端启动中......");
		//1. 创建接收端socket,指定端口
		DatagramSocket server = new DatagramSocket(9999);
		//2. 准备容器,封装成包裹
		byte[] container = new byte[1024 * 64];
		DatagramPacket packet = new DatagramPacket(container, 0, container.length);
		//3. 接收数据
		server.receive(packet);
		//4. 分析处理数据,第一步肯定是获取字节数组,然后再对字节数组进行分析
		byte[] datas = packet.getData();
		int len = packet.getLength();
		String destination = "F:/myjava/Net_Study02/src/images/plane_copy.png";
		IOUtils.byteArrayToFile(datas, destination);
		//5. 释放资源
		server.close();
	}
}

发送端
code

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

public class UdpFileClient {
	public static void main(String[] args) throws IOException{
		System.out.println("发送端启动中......");
		//1. 创建发送端socket,指定端口
		DatagramSocket client = new DatagramSocket(8888);
		//2. 准备发送数据,需要将文件转为字节数组
		String source = "F:/myjava/Net_Study02/src/images/plane.png";
		byte[] datas = IOUtils.fileToByteArray(source);
		//3. 将数据封装成包裹,添加接收端IP及Port
		DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("127.0.0.1", 9999));
		//4. 发送数据
		client.send(packet);
		//5. 释放资源
		client.close();
		
	}
}

数据转换方法类(IOUtils)

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IOUtils {
	/**
	 * 将图片读到字节数组中
	 * 1. 图片-->程序
	 * 2. 程序-->字节数组
	 * @param src
	 * @param datas
	 */
	public static byte[] fileToByteArray(String src){
		//1. 创建源
		File picture = new File(src);
		//2. 选择流
		InputStream fis = null;
		ByteArrayOutputStream baos = null;
		try {
			//2.1 初始化文件读入流对象
			fis = new FileInputStream(picture);
			//2.2 
			baos = new ByteArrayOutputStream();
			//3. 读文件
			int len = -1;
			byte[] flush = new byte[1024*10];
			while((len = fis.read(flush)) != -1){
				baos.write(flush, 0, len);	//将flush中的内容写出到字节数组中
			}
			//释放资源
			baos.flush();
			fis.close();
			
			return baos.toByteArray();		//返回内存中的字节数组
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e){
			e.printStackTrace();
		} finally{
			try {
				if(null != fis){
					fis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;	//出错
	}
	/**
	 * 将内存中的字节数组还原为图片
	 * 1. 字节数组 ---> 程序
	 * 2. 程序 --->图片
	 * @param datas
	 * @param dest
	 */
	public static void byteArrayToFile(byte[] datas, String dest){
		//1. 创建源
		File picture = new File(dest);
		//2. 选择流
		InputStream bais = null;
		OutputStream os = null;
		//2.1 创建字节输入流对象
		bais = new ByteArrayInputStream(datas);
		try {
			//2.2 创建字节输出流对象
			os = new FileOutputStream(picture, true);	//append
			//3. 读字节数组
			byte[] flush = new byte[5];
			int len = -1;
			while((len = bais.read(flush)) != -1){
				os.write(flush, 0, len);	//向文件中写数据
			}
			os.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e){
			e.printStackTrace();
		} finally{
			try{
				if(null != os){
					os.close();
				}
			} catch(IOException e){
				e.printStackTrace();
			}
		}
	}
}

总结

      如果只是使用UDP进行单向传递数据,且数据只传送一次,那么严格按照上述步骤进行操作即可。上述三种数据的传送方式都有固定的代码格式,只是在将数据转为字节数组时和将字节数组转为数据时不同。当然这也是合乎道理的,java提供的包为我们封装好了传送数据的方法,我们上层开发人员只需注重字节数组数据,IP和端口就好了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值