java与网络(UDP)

1. UDP收发的基本操作

数据报的大小限制在64K之内。

  • 报文的接收
System.out.println("接收方启动中.....");
// 1、使用DatagramSocket  指定端口 创建接收端
DatagramSocket server =new DatagramSocket(6666); //服务器端侦听的端口
// 2、准备容器 封装成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive​(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析数据
//    byte[]  getData​()
//                getLength​()
 byte[]  datas =packet.getData();
 int len = packet.getLength();
 System.out.println(new String(datas,0,len));
 
// 5、释放资源
 server.close();
  • 报文的发送
System.out.println("发送方启动中.....");
 // 1、使用DatagramSocket  指定端口 创建发送端
DatagramSocket client =new DatagramSocket(8888); //发送端的源端口
 //2、准备数据 一定转成字节数组
String data = "黑夜给了我黑色的眼睛";
byte[] datas = data.getBytes("UTF8"); 
 //3、 封装成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
		new InetSocketAddress("localhost",6666)); //发送端的目的地址和端口号
//4、发送包裹send​(DatagramPacket p) * 
client.send(packet);
// 5、释放资源
client.close();
  • 如何在eclipse中开启多个console窗口

    拖动调整Console窗口的位置,然后钉住

    选择console控制台窗口
2. UDP收发基本数据类型
  • 报文的接收
System.out.println("接收方启动中.....");
// 1、使用DatagramSocket  指定端口 创建接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、准备容器 封装成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive​(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析数据    将字节数组还原为对应的类型
//    byte[]  getData​()
//                getLength​()
 byte[]  datas =packet.getData();
 int len = packet.getLength();		 
DataInputStream dis =new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//顺序与写出一致
String msg = dis.readUTF(); 
int age = dis.readInt();
boolean flag = dis.readBoolean();
char ch = dis.readChar();
System.out.println(msg+"-->"+flag);
// 5、释放资源
server.close();
  • 报文的发送
System.out.println("发送方启动中.....");
 // 1、使用DatagramSocket  指定端口 创建发送端
DatagramSocket client =new DatagramSocket(8888);
 //2、准备数据 一定转成字节数组
//写出
ByteArrayOutputStream baos =new ByteArrayOutputStream();
DataOutputStream dos =new DataOutputStream(new BufferedOutputStream(baos));
//操作数据类型 +数据
dos.writeUTF("编码辛酸泪");
dos.writeInt(18);
dos.writeBoolean(false);
dos.writeChar('a');
dos.flush();
byte[] datas =baos.toByteArray();	
 //3、 封装成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
		new InetSocketAddress("localhost",6666));
//4、发送包裹send​(DatagramPacket p) * 
client.send(packet);
// 5、释放资源
client.close();
3. UDP收发对象
  • 报文的接收
System.out.println("接收方启动中.....");
// 1、使用DatagramSocket  指定端口 创建接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、准备容器 封装成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive​(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析数据    将字节数组还原为对应的类型
 byte[]  datas =packet.getData();
 int len = packet.getLength();		 
//读取 -->反序列化
ObjectInputStream ois =new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//顺序与写出一致,对象的数据还原
Object str = ois.readObject();
Object date = ois.readObject();
Object employee = ois.readObject();

if(str instanceof String) {
	String strObj = (String) str;
	System.out.println(strObj);
}
if(date instanceof Date) {
	Date dateObj = (Date) date;
	System.out.println(dateObj);
}
if(employee instanceof Employee) {
	Employee empObj = (Employee) employee;
	System.out.println(empObj.getName()+"-->"+empObj.getSalary());
}
// 5、释放资源
 server.close();
  • 报文的发送
System.out.println("发送方启动中.....");
 // 1、使用DatagramSocket  指定端口 创建发送端
DatagramSocket client =new DatagramSocket(8888);
 //2、准备数据 一定转成字节数组
//写出
ByteArrayOutputStream baos =new ByteArrayOutputStream();
ObjectOutputStream oos =new ObjectOutputStream(new BufferedOutputStream(baos));
//对象
oos.writeObject("我却用它来寻找光明");
oos.writeObject(new Date());
Employee emp =new Employee("欧阳克",400);
oos.writeObject(emp);
oos.flush();
byte[] datas =baos.toByteArray();	

 //3、 封装成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
		new InetSocketAddress("localhost",6666));
//4、发送包裹
client.send(packet);
// 5、释放资源
client.close();
4. 传输文件(小文件)
  • 工具类
public class IOUtils {
	/**
	 * 1、图片读取到字节数组
	 * 1)、图片到程序  FileInputStream
	 * 2)、程序到字节数组	ByteArrayOutputStream
	 */
	public static byte[] fileToByteArray(String filePath) {
		//1、创建源与目的地
		File src = new File(filePath);
		byte[] dest =null;
		//2、选择流
		InputStream  is =null;
		ByteArrayOutputStream baos =null;
		try {
			is =new FileInputStream(src);
			baos = new ByteArrayOutputStream();
			//3、操作 (分段读取)
			byte[] flush = new byte[1024*10]; //缓冲容器
			int len = -1; //接收长度
			while((len=is.read(flush))!=-1) {
				baos.write(flush,0,len);		 //写出到字节数组中			
			}		
			baos.flush();
			return baos.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4、释放资源
			try {
				if(null!=is) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;		
	}
	/**
	 * 2、字节数组写出到图片
	 * 1)、字节数组到程序 ByteArrayInputStream
	 * 2)、程序到文件 FileOutputStream
	 */
	public static void byteArrayToFile(byte[] src,String filePath) {
		//1、创建源
		File dest = new File(filePath);
		//2、选择流
		InputStream  is =null;
		OutputStream os =null;
		try {
			is =new ByteArrayInputStream(src);
			os = new FileOutputStream(dest);
			//3、操作 (分段读取)
			byte[] flush = new byte[5]; //缓冲容器
			int len = -1; //接收长度
			while((len=is.read(flush))!=-1) {
				os.write(flush,0,len);			//写出到文件	
			}		
			os.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4、释放资源
			try {
				if (null != os) {
					os.close();
				} 
			} catch (Exception e) {
			}
		}
	}
}
  • 文件的接收
System.out.println("接收方启动中.....");
// 1、使用DatagramSocket  指定端口 创建接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、准备容器 封装成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive​(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析数据    将字节数组还原为对应的类型
//    byte[]  getData​()
//                getLength​()
 byte[]  datas =packet.getData();
 int len = packet.getLength();		 
 IOUtils.byteArrayToFile(datas, "src/copy.png");		 
// 5、释放资源
server.close();
  • 文件的发送
System.out.println("发送方启动中.....");
 // 1、使用DatagramSocket  指定端口 创建发送端
DatagramSocket client =new DatagramSocket(8888);
 //2、准备数据 一定转成字节数组
byte[] datas =IOUtils.fileToByteArray("src/logo.png");		
 //3、 封装成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
		new InetSocketAddress("localhost",6666));
//4、发送包裹send​(DatagramPacket p) * 
client.send(packet);
// 5、释放资源
client.close();
5. 多次发送,多次接收
  • 接收端
System.out.println("接收方启动中.....");
// 1、使用DatagramSocket  指定端口 创建接收端
DatagramSocket server =new DatagramSocket(6666);

while(true) {
	// 2、准备容器 封装成DatagramPacket 包裹
	byte[] container =new byte[1024*60];
	DatagramPacket packet = new DatagramPacket(container,0,container.length);
	// 3、阻塞式接收包裹receive​(DatagramPacket p)
	server.receive(packet); //阻塞式
	// 4、分析数据
	//    byte[]  getData​()
	//                getLength​()
	 byte[]  datas =packet.getData();
	 int len = packet.getLength();
	 String data=new String(datas,0,len);
	 System.out.println(data);
	 if(data.equals("bye")) {
		 break;
	 }
}
// 5、释放资源
server.close();
  • 发送端
System.out.println("发送方启动中.....");
 // 1、使用DatagramSocket  指定端口 创建发送端
DatagramSocket client =new DatagramSocket(8888);
 //2、准备数据 一定转成字节数组
BufferedReader reader =new BufferedReader(new InputStreamReader(System.in));
while(true) {
	String data = reader.readLine();
	byte[] datas = data.getBytes();
	 //3、 封装成DatagramPacket 包裹,需要指定目的地
	DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
			new InetSocketAddress("localhost",6666));
	//4、发送包裹send​(DatagramPacket p) * 
	client.send(packet);
	if(data.equals("bye")) {
		break;
	}
}
// 5、释放资源
client.close();
6. 全双工通信

引入多线程

  • 接收器
public class TalkReceive implements Runnable {
	private DatagramSocket server;
	private String from;

	public TalkReceive(int port, String from) {
		this.from = from;
		try {
			server = new DatagramSocket(port);
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		while (true) {
			byte[] container = new byte[1024 * 60];
			DatagramPacket packet = new DatagramPacket(container, 0, container.length);
			try {
				server.receive(packet);// 阻塞式接收
				byte[] datas = packet.getData();
				int len = packet.getLength();
				String data = new String(datas, 0, len);
				System.out.println(from + ":" + data);
				if (data.equals("bye")) {
					break;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		server.close();
	}
}
  • 发送器
public class TalkSend implements Runnable {
	private DatagramSocket client;
	private BufferedReader reader;
	private String destIP;
	private int destPort;

	public TalkSend(int srcPort, String destIP, int destPort) {
		this.destIP = destIP;
		this.destPort = destPort;
		try {
			client = new DatagramSocket(srcPort);
			reader = new BufferedReader(new InputStreamReader(System.in));
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		while (true) {
			String data;
			try {
				data = reader.readLine(); // 阻塞读取控制台输入
				byte[] datas = data.getBytes();
				DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
						new InetSocketAddress(this.destIP, this.destPort));
				client.send(packet);
				if (data.equals("bye")) {
					break;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		client.close();
	}

}
  • 对等通信端(屌丝 )
new Thread(new TalkSend(6100, "localhost", 8847)).start(); // 发送
new Thread(new TalkReceive(8848, "长腿皮裤妹")).start(); // 接收
  • 对等通信端(长腿皮裤妹)
new Thread(new TalkSend(6120, "localhost", 8848)).start(); // 发送
new Thread(new TalkReceive(8847, "屌丝")).start(); // 接收
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值