基本类型数据传输
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和端口就好了。