一、简单实现发送端与接收端的传输
发送端
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(); //接收端口
}
}