学习重点还是在熟练使用Udp上,对于文件流的的知识前面的博客中有详细介绍
传输基本类型, 使用数据流DataOutputStream和DataInputStream
客户端
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;
/*
* 发送端
* 1.DatagramSocket指定端口,创建发送端
* 2.准备数据 基本类型转换为字节数组
* 3.封装成DatagramPacket包裹 指定目的
* 4.send(DatagramPacket p)发送包裹
* 5.释放资源
*/
public class udpTypeClient {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动");
//1.DatagramSocket指定端口,创建发送端
DatagramSocket client = new DatagramSocket(9999);
//2.准备数据 基本类型转换为字节数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
dos.writeUTF("编程辛酸史");
dos.writeInt(18);
dos.writeBoolean(true);
dos.writeChar('A');
dos.flush();
byte[] datas = baos.toByteArray();
//3.封装成DatagramPacket包裹 指定目的DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress("localhost", 8888));
//4.send(DatagramPacket p)发送包裹
client.send(packet);
//5.释放资源
client.close();
}
}
服务端
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.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
* 4.解析数据为对应基本类型
* 5.释放资源
*/
public class udpTypeServer {
public static void main(String[] args) throws IOException {
System.out.println("接收端启动");
//1.DatagramSocket指定端口,创建接收端
DatagramSocket server = new DatagramSocket(8888);
//2.准备容器封装成DatagramPacket包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//3.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
server.receive(packet);
//4.解析数据为对应基本类型
byte[] datas = packet.getData();
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);
System.out.println(age);
System.out.println(flag);
System.out.println(ch);
//5.释放资源
server.close();
}
}
传输对象使用 对象字节流ObjectInputStream、ObjectOutputStream
客户端
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
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.释放资源
*/
public class udpObjectClient {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动");
//1.DatagramSocket指定端口,创建发送端
DatagramSocket client = new DatagramSocket(9999);
//2.准备数据 基本类型转换为字节数组
//写出(序列化 serialization)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(baos));
//操作数据(类型)
oos.writeUTF("编码辛酸泪");
oos.writeInt(18);
oos.writeBoolean(false);
oos.writeChar('b');
oos.writeObject(new String("谁解其中味"));
oos.writeObject(new Date());
Employee emp = new Employee("远哥", 999999.99);
oos.writeObject(emp);
oos.flush();
byte[] datas = baos.toByteArray();
//3.封装成DatagramPacket包裹 指定目的DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress("localhost", 8888));
//4.send(DatagramPacket p)发送包裹
client.send(packet);
//5.释放资源
client.close();
}
}
服务端
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.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
* 4.解析数据为对应基本类型
* 5.释放资源
*/
public class udpObjectServer {
public static void main(String[] args) throws IOException, ClassNotFoundException {
System.out.println("接收端启动");
//1.DatagramSocket指定端口,创建接收端
DatagramSocket server = new DatagramSocket(8888);
//2.准备容器封装成DatagramPacket包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//3.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
server.receive(packet);
//4.解析数据为对应基本类型
byte[] datas = packet.getData();
//读取(反序列化 deserialization)
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
String msgString = ois.readUTF();
int integer = ois.readInt();
Boolean bool = ois.readBoolean();
char c = ois.readChar();
System.out.println(msgString);
System.out.println(integer);
System.out.println(bool);
System.out.println(c);
Object strObj = ois.readObject();
Object dObj = ois.readObject();
Object employeeObj = ois.readObject();
//类型转换要加判断
if(strObj instanceof String) {
String str = (String)strObj;
System.out.println(str);
}
if(dObj instanceof Date) {
Date d = (Date)dObj;
System.out.println(d);
}
if(employeeObj instanceof Employee) {
Employee employee = (Employee)employeeObj;
System.out.println(employee);
}
//5.释放资源
server.close();
}
}
传输图片使用 字节流ObjectInputStream、ObjectOutputStream
使用对接流学习时封装过的图片和字节流转换类
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 pictureToByteArray {
//图片转为字节数组
public static byte[] fileToByteArray(String filePath) {
//创建源与目的�?
File src = new File(filePath);
//选择�?
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
is = new FileInputStream(src);
baos = new ByteArrayOutputStream();
//分段读取
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 {
//释放资源
try {
if(null != is)
is.close();
}catch(IOException e) {
e.printStackTrace();
}
}
return null;
}
//将字节数组写回图片文�?
public static void byteArrayToFile(byte[] src, String filePath) {
//�?
File dest = new File(filePath);
//�?
InputStream is = null;
OutputStream os = null;
try {
is = new ByteArrayInputStream(src);
os = new FileOutputStream(dest);
//操作
byte[] flush = new byte[5]; //缓冲容器
int len = -1;
while((len = is.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();
}
try {
if(null != is) {
is.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
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.释放资源
*/
public class udpPicClient {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动");
//1.DatagramSocket指定端口,创建发送端
DatagramSocket client = new DatagramSocket(9999);
//2.准备数据 转换为字节数组
// byte[] datas = pictureToByteArray.fileToByteArray("E:/源库/源代码/Java/Net01/pic.jpg");
// byte[] datas = pictureToByteArray.fileToByteArray("E:/源库/源代码/Java/Net01/whale.jpg");
byte[] datas = pictureToByteArray.fileToByteArray("E:/源库/源代码/Java/Net01/obj.jpg");
//3.封装成DatagramPacket包裹 指定目的DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress("localhost", 8888));
//4.send(DatagramPacket p)发送包裹
client.send(packet);
//5.释放资源
client.close();
}
}
服务端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 接收端
* 1.DatagramSocket指定端口,创建接收端
* 2.准备容器封装成DatagramPacket包裹
* 3.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
* 4.解析数据DatagramPacket的成员函数byte[] getData()
* 5.释放资源
*/
public class udpPicServer {
public static void main(String[] args) throws IOException {
System.out.println("接收端启动");
//1.DatagramSocket指定端口,创建接收端
DatagramSocket server = new DatagramSocket(8888);
//2.准备容器封装成DatagramPacket包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//3.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
server.receive(packet);
//4.解析数据
byte[] datas = packet.getData();
pictureToByteArray.byteArrayToFile(datas, "E:/源库/源代码/Java/Net01/copy.jpg");
//5.释放资源
server.close();
}
}
发现太大的图片会报异常
实现一个可以持续发送消息的客户端和持续接收消息的服务端
客户端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
/*
* 发送端:持续交流
* 1.DatagramSocket指定端口,创建发送端
* 2.准备数据 转换为字节数组
* 3.封装成DatagramPacket包裹 指定目的
* 4.send(DatagramPacket p)发送包裹
* 5.释放资源
*/
public class udpTalkClient {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动");
//1.DatagramSocket指定端口,创建发送端
DatagramSocket client = new DatagramSocket(9999);
//2.准备数据 转换为字节数组/除了scanner还可以使用bufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //InputStreamReader字节-->字符
while(true) {
String data = br.readLine();
byte[] datas = data.getBytes();
//3.封装成DatagramPacket包裹 指定目的DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress("localhost", 8888));
//4.send(DatagramPacket p)发送包裹
client.send(packet);
if(data.equals("bye"))
break;
}
//5.释放资源
client.close();
}
}
服务端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 接收端:持续交流
* 1.DatagramSocket指定端口,创建接收端
* 2.准备容器封装成DatagramPacket包裹
* 3.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
* 4.解析数据DatagramPacket的成员函数byte[] getData()
* 5.释放资源
*/
public class udpTalkServer {
public static void main(String[] args) throws IOException {
System.out.println("接收端启动");
//1.DatagramSocket指定端口,创建接收端
DatagramSocket server = new DatagramSocket(8888);
while(true) {
//2.准备容器封装成DatagramPacket包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//3.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
server.receive(packet);
//4.解析数据
byte[] datas = packet.getData();
int len = packet.getLength();
String datas1 = new String(datas, 0, len);
System.out.println(datas1);
if(datas1.equals("bye"))
break;
}
//5.释放资源
server.close();
}
}
实现一个在线双向沟通平台
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;
/*
* 发送端
*/
public class send implements Runnable{
private DatagramSocket client;
private BufferedReader br;
private String otherIPString;
private int otherPort;
public send(int port, String otherIPString, int otherPort) {
super();
this.otherIPString = otherIPString;
this.otherPort = otherPort;
try {
client = new DatagramSocket(port);
br = new BufferedReader(new InputStreamReader(System.in)); //InputStreamReader字节-->字符
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
String data;
try {
data = br.readLine();
byte[] datas = data.getBytes();
//3.封装成DatagramPacket包裹 指定目的DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
new InetSocketAddress(otherIPString, otherPort));
//4.send(DatagramPacket p)发送包裹
client.send(packet);
if(data.equals("bye"))
break;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//5.释放资源
client.close();
}
}
接收端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/*
* 接收端
*/
public class receive implements Runnable{
private DatagramSocket server;
public receive(int port) {
super();
try {
this.server = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
//2.准备容器封装成DatagramPacket包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container, 0, container.length);
//3.调用DatagramSocket的成员方法函数void receive(DatagramPacket p)阻塞式接收包裹
try {
server.receive(packet);
//4.解析数据
byte[] datas = packet.getData();
int len = packet.getLength();
String datas1 = new String(datas, 0, len);
System.out.println(datas1);
if(datas1.equals("bye"))
break;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//5.释放资源
server.close();
}
}
创建两个端
public class teacher {
public static void main(String[] args) {
new Thread(new receive(9999)).start(); //接收
new Thread(new send(7776, "localhost", 8888)).start(); //发送
}
}
public class student {
public static void main(String[] args) {
new Thread(new send(7777, "localhost", 9999)).start(); //发送
new Thread(new receive(8888)).start(); //接收
}
}