模拟客户端,服务端图片上传
使用Java io流、线程池、socket网络编程模拟客户端上传图片到服务端,服务端保存文件
自定义线程池
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
//线程池处理类
public class HandlerSocketThreadPool {
//线程池
private ExecutorService executor;
//线程池:3个线程 100个
public HandlerSocketThreadPool(int maxPoolSize, int queueSize) {
executor = new ThreadPoolExecutor(
maxPoolSize,
maxPoolSize,
120L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(queueSize)
);
}
public void execute(Runnable task) {
this.executor.execute(task);
}
}
服务端
import java.net.ServerSocket;
import java.net.Socket;
/**
* 功能点:
* 1.接收多个服务端传输来的图片数据存储到服务器路径:day_06/src/test
* 2.响应一个成功的消息给当前客户端
*/
public class ServerDemo {
public static final String DEST_PATH = "demo/src/test";
public static void main(String[] args) throws Exception {
System.out.println("-------服务端启动-------");
//1.注册端口
ServerSocket ss = new ServerSocket(8081);
//一个服务器对应一个线程池
HandlerSocketThreadPool pool = new HandlerSocketThreadPool(3, 100);
//定义一个循环不断的接收客户端的连接请求
while (true) {
//2.开始等待接收客户端的Socket连接
Socket socket = ss.accept();
pool.execute(new ReaderClientRunnable(socket, DEST_PATH));
}
}
}
线程任务类
处理客户端发来的数据,保存到本地
import java.io.*;
import java.net.Socket;
import java.util.UUID;
public class ReaderClientRunnable implements Runnable{
private Socket socket;
private String destPath;
public ReaderClientRunnable(Socket socket, String destPath) {
this.socket = socket;
this.destPath = destPath;
}
@Override
public void run() {
try {
//1.从socket通信管道中得到一个字节输入流
InputStream is = socket.getInputStream();
//2.把低级字节输入流包装成高级字节缓冲流
InputStream bis = new BufferedInputStream(is);
//获取一个通向服务器路径的字节输出流
OutputStream os = new FileOutputStream(destPath + "/" + UUID.randomUUID() + ".jpg");
//包装
OutputStream bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.flush();
bos.close();
//给客户端返回消息
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("谢谢!");
ps.flush();
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
System.out.println(socket.getRemoteSocketAddress() + "下线了!!!");
}
}
}
客户端
import java.io.*;
import java.net.Socket;
/**
* 目标:实现客户端上传图片给服务端保存起来
*
* 开发客户端:本地照片:C:/Users/Pictures/Saved Pictures/test.jpg
* 开发服务端:服务器路径:demo/src/test
*/
public class ClientDemo {
public static final String LOCAL_PATH = "C:/Users/Pictures/Saved Pictures/test.jpg";
public static void main(String[] args) throws Exception {
//1.请求于服务器的Socket通信管道
Socket socket = new Socket("192.168.4.216", 8081);
//2.从socket得到一个字节输出流管道
OutputStream os = socket.getOutputStream();
//3.包装成缓冲字节输出流
OutputStream bos = new BufferedOutputStream(os);
//读取本地上传的文件写入管道
InputStream is = new FileInputStream(LOCAL_PATH);
InputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.flush();
bis.close();
//通知服务端我的数据已发送完毕
socket.shutdownOutput();
System.out.println("客户端传输图片完成!");
//接收服务端发回来的响应消息
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
}
}