网络编程_UDP

一、简单实现发送端与接收端的传输
发送端

package com.sxt.udp;

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

/**
 * 发送端
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.准备数据  一定转成字节数组
 * 3.封装成DatagramPacket包裹,需要指定目的地
 * 4.发送包裹 send(DatagramPacket p)
 * 5.释放资源
 * @author Hao Chen
 *
 */

public class UdpClient {
	public static void main(String[] args) throws IOException {
		System.out.println("发送方启动中...");
		//1.使用DatagramSocket 指定端口 创建发送端
		DatagramSocket client=new DatagramSocket(8888);
		// 2.准备数据  一定转成字节数组
		String data="晚上好";
		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);
		//5.释放资源
		client.close();
				
	}

}

接收端

package com.sxt.udp;

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

/**
 * 接收端
 * Address already in use: Cannot bind  同一个协议下端口不允许冲突
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.准备容器  封装成DatagramPacket包裹
 * 3.阻塞式接收包裹 receive(DatagramPacket p)
 * 4.分析数据
 * byte getData()
 *      getLength()
 * 5.释放资源
 * @author Hao Chen
 *
 */

public class UdpServer {
	public static void main(String[] args) throws IOException {
		// 1.使用DatagramSocket 指定端口 创建接收端
		DatagramSocket server=new DatagramSocket(6666);
		//2.准备容器  封装成DatagramPacket包裹
		byte[] container=new byte[1024*10];
		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();
	}

}

二、实现发送端与接收端的基本数据类型的传输**

发送端

package com.sxt.udp;

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

/**
 * 发送端
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.将基本类型转成字节数组
 * 3.封装成DatagramPacket包裹,需要指定目的地
 * 4.发送包裹 send(DatagramPacket p)
 * 5.释放资源
 * @author Hao Chen
 *
 */

public class UdpTypeClient {
	public static void main(String[] args) throws IOException {
		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.writeChar('a');
				dos.writeBoolean(false);
				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();
				
	}

}

接收端

package com.sxt.udp;

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

/**
 * 引用类型:接收端
 * Address already in use: Cannot bind  同一个协议下端口不允许冲突
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.准备容器  封装成DatagramPacket包裹
 * 3.阻塞式接收包裹 receive(DatagramPacket p)
 * 4.分析数据
 * byte getData()
 *      getLength()
 * 5.释放资源
 * @author Hao Chen
 *
 */

public class UdpTypeServer {
	public static void main(String[] args) throws IOException {
		// 1.使用DatagramSocket 指定端口 创建接收端
		DatagramSocket server=new DatagramSocket(6666);
		//2.准备容器  封装成DatagramPacket包裹
		byte[] container=new byte[1024*10];
		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 num=dis.readInt();
				char c=dis.readChar();
				System.out.println(msg);
				System.out.println(num);
				
		//5.释放资源
		server.close();
	}

}

三、实现发送端与接收端的引用数据类型的传输

发送端

package com.sxt.udp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.Date;

/**
 * 发送端
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.将基本类型转成字节数组
 * 3.封装成DatagramPacket包裹,需要指定目的地
 * 4.发送包裹 send(DatagramPacket p)
 * 5.释放资源
 * @author Hao Chen
 *
 */

public class UdpObjectClient {
	public static void main(String[] args) throws IOException {
		System.out.println("发送方启动中...");
		//1.使用DatagramSocket 指定端口 创建发送端
		DatagramSocket client=new DatagramSocket(8888);
		// 2.准备数据  一定转成字节数组
		//写出
		ByteArrayOutputStream baos=new ByteArrayOutputStream();
		ObjectOutputStream oos=new ObjectOutputStream(new BufferedOutputStream(baos));
		
		//操作数据类型+数据
		oos.writeUTF("我太难啦");
		oos.writeInt(18);
		oos.writeChar('a');
		oos.writeBoolean(false);
		oos.writeObject(new Date());
		oos.writeObject("how many days");
		oos.writeObject(new Employee("詹姆斯",20000,"洛杉矶湖人"));
		oos.flush();
		
		byte[] datas=baos.toByteArray();
		oos.close();
		//3.封装成DatagramPacket包裹,需要指定目的地
		DatagramPacket packet=new DatagramPacket(datas,0, datas.length,
				new InetSocketAddress("localhost",6666));
		
		//4.发送包裹 send(DatagramPacket p)
		client.send(packet);
		//5.释放资源
		client.close();
				
	}

}

class Employee implements java.io.Serializable{
	
	private String name;
	private double salary;
	private transient String address;    //透明化,反序列化时看不到
	
	public Employee(String name, double salary, String address) {
		super();
		this.name = name;
		this.salary = salary;
		this.address = address;
	}

	public Employee() {
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}
}

接收端

package com.sxt.udp;

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

/**
 * 基本类型:接收端
 * Address already in use: Cannot bind  同一个协议下端口不允许冲突
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.准备容器  封装成DatagramPacket包裹
 * 3.阻塞式接收包裹 receive(DatagramPacket p)
 * 4.分析数据
 * byte getData()
 *      getLength()
 * 5.释放资源
 * @author Hao Chen
 *
 */

public class UdpObjectServer {
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		// 1.使用DatagramSocket 指定端口 创建接收端
		DatagramSocket server=new DatagramSocket(6666);
		//2.准备容器  封装成DatagramPacket包裹
		byte[] container=new byte[1024*10];
		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();   //获取发送的数据长度
		//读取
		ObjectInputStream ois=new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
		
		//读的顺序要跟写的顺序一致,否则会出现异常
		String msg=ois.readUTF();
		int num=ois.readInt();
		char c=ois.readChar();
		
		System.out.println(ois.readBoolean());
		Object date=ois.readObject();
		Object str=ois.readObject();
		Object emp=ois.readObject();
		ois.close();
		if(date instanceof Date){
			Date dateObj=(Date)date;
			System.out.println(dateObj);
		}
		
		if(str instanceof String){
			String strObj=(String)str;
			System.out.println(strObj);
		}
		
		if(emp instanceof Employee){
			Employee empObj=(Employee)emp;
			System.out.println(empObj.getName()+"---"+empObj.getSalary()+"---"+empObj.getAddress());
		}
				
		//5.释放资源
		server.close();
	}

}

四、实现发送端与接收端的文件类型的传输

发送端

package com.sxt.udp;

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

/**
 * 文件上传 发送端
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.准备数据  一定转成字节数组
 * 3.封装成DatagramPacket包裹,需要指定目的地
 * 4.发送包裹 send(DatagramPacket p)
 * 5.释放资源
 * @author Hao Chen
 *
 */

public class UdpFileClient {
	public static void main(String[] args) throws IOException {
		System.out.println("发送方启动中...");
		//1.使用DatagramSocket 指定端口 创建发送端
		DatagramSocket client=new DatagramSocket(8888);
		// 2.准备数据  一定转成字节数组
		byte[] datas=IOUtils.filetoByteArray("src/a.txt");
		//3.封装成DatagramPacket包裹,需要指定目的地
		DatagramPacket packet=new DatagramPacket(datas,0, datas.length,
				new InetSocketAddress("localhost",6666));
		
		//4.发送包裹 send(DatagramPacket p)
		client.send(packet);
		//5.释放资源
		client.close();
				
	}

}

接收端

package com.sxt.udp;

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

/**
 * 文件存储 接收端
 * Address already in use: Cannot bind  同一个协议下端口不允许冲突
 * 1.使用DatagramSocket 指定端口 创建接收端
 * 2.准备容器  封装成DatagramPacket包裹
 * 3.阻塞式接收包裹 receive(DatagramPacket p)
 * 4.分析数据
 * byte getData()
 *      getLength()
 * 5.释放资源
 * @author Hao Chen
 *
 */

public class UdpFileServer {
	public static void main(String[] args) throws IOException {
		// 1.使用DatagramSocket 指定端口 创建接收端
		DatagramSocket server=new DatagramSocket(6666);
		//2.准备容器  封装成DatagramPacket包裹
		byte[] container=new byte[1024*10];
		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/a-copy.txt");
		//5.释放资源
		server.close();
	}

}

文件转换到字节数组与字节数组输出到文件的转换类

package com.sxt.udp;

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 {
	/**
	 * 图片读取到字节数组
	 * 图片读到程序
	 * 程序写出到字节数组
	 * 
	 */
	
	public static byte[] filetoByteArray(String srcPath){
		//1.创建源
				File src=new File(srcPath);
				byte[] dest=null;
				//2.选择流
				InputStream is=null;
				ByteArrayOutputStream os=null;
				
				try {
					is=new FileInputStream(src);
					os=new ByteArrayOutputStream();
					//3.操作(一段一段读取)
					byte[] flush=new byte[1024*10];
					int len=-1;
					while((len=is.read(flush))!=-1){   //图片读出来
						os.write(flush, 0, len);    //写出到字节数组中
					}
					os.flush();
					return os.toByteArray();
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally{
					//4.释放资源
						try {
							if(is!=null){
							is.close();
							}
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
				 }
				return null;
	}

	/**
	 * 字节数组写出到图片
	 * @param src
	 * @param destPath
	 */
	
	public static void byteArrayToFile(byte[] src,String destPath){
		//1.创建源
				File dest=new File(destPath);
				
				//2.选择流
				ByteArrayInputStream is=null;
				OutputStream os=null;
				try {
					is=new ByteArrayInputStream(src);
					os=new FileOutputStream(dest);
					//3.操作(写出内容)
					int len=-1;
					byte[] flush=new byte[1024*20];
					while((len=is.read(flush))!=-1){
						os.write(flush,0,len);   //写出到文件
					}
					os.flush();
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally{
					//4.释放资源
					try {
						if(os!=null){
							os.close();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
	}
}

五、面向对象思想,多线程实现一对一简易聊天

发送端实现Runnable接口

package com.sxt.udp;

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

/**
 * 发送端
 * @author Hao Chen
 *
 */

public class TalkSend implements Runnable {
	private DatagramSocket client;
	private BufferedReader reader;
	private String toIP; //对方的ip地址
	private int toPort; //对方的端口
	private DatagramPacket packet;
	public TalkSend(int port,String toIP,int toPort) {
		this.toIP=toIP;
		this.toPort=toPort;
		try {
			client=new DatagramSocket(port);
			reader=new BufferedReader(new InputStreamReader(System.in));
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void run(){
		while(true){
			String data;
			try {
				data = reader.readLine();
				byte[] datas=data.getBytes(); 
				//3.封装成DatagramPacket包裹,需要指定目的地
				DatagramPacket packet=new DatagramPacket(datas,0, datas.length,
						new InetSocketAddress(this.toIP,this.toPort));
				
				//4.发送包裹 send(DatagramPacket p)
				client.send(packet);
				if(data.equals("bye bye")){
					break;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

接收端实现Runnable接口

package com.sxt.udp;

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

/**
 * 接收端:使用面向对象封装
 * @author Hao Chen
 *
 */

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) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void run(){
		while(true){
			byte[] container=new byte[1024*10];
			DatagramPacket packet=new DatagramPacket(container, 0, container.length);
			//3.阻塞式接收包裹 receive(DatagramPacket p)
			try {
				server.receive(packet);
				// 4.分析数据
				//byte[] getData()
				 //      getLength()
				byte[] datas=packet.getData();  //获取字节数组
				int len=packet.getLength();   //获取发送的数据长度
				String msg=new String(datas,0,len);
				System.out.println(from+":"+msg);
				if(msg.equals("bye bye")){
					break;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}
}

老师与学生两个线程模拟对话

package com.sxt.udp;

/**
 * 加入多线程,实现双向交流 模拟在线咨询
 * @author Hao Chen
 *
 */

public class TalkTeacher {
	public static void main(String[] args) {
		new Thread(new TalkReceive(9999,"学生")).start();  //接收端口
		new Thread(new TalkSend(8970,"localhost",8888)).start();  //发送端口
		
	}
}

package com.sxt.udp;

/**
 * 加入多线程,实现双向交流 模拟在线咨询
 * @author Hao Chen
 *
 */

public class TalkStudent {
	public static void main(String[] args) {
		new Thread(new TalkSend(7777,"localhost",9999)).start();  //发送端口
		new Thread(new TalkReceive(8888,"老师")).start();  //接收端口
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值