练习四:文件名重复
public class UUIDTest { public static void main(String[] args) { String str = UUID.randomUUID().toString().replace("-", ""); System.out.println(str);//9f15b8c356c54f55bfcb0ee3023fce8a } } ``` public class Client { public static void main(String[] args) throws IOException { //客户端:将本地文件上传到服务器。接收服务器的反馈。 //服务器:接收客户端上传的文件,上传完毕之后给出反馈。 //1. 创建Socket对象,并连接服务器 Socket socket = new Socket("127.0.0.1",10000); //2.读取本地文件中的数据,并写到服务器当中 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("mysocketnet\\clientdir\\a.jpg")); BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); byte[] bytes = new byte[1024]; int len; while ((len = bis.read(bytes)) != -1){ bos.write(bytes,0,len); } //往服务器写出结束标记 socket.shutdownOutput(); //3.接收服务器的回写数据 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = br.readLine(); System.out.println(line); //4.释放资源 socket.close(); } } public class Server { public static void main(String[] args) throws IOException { //客户端:将本地文件上传到服务器。接收服务器的反馈。 //服务器:接收客户端上传的文件,上传完毕之后给出反馈。 //1.创建对象并绑定端口 ServerSocket ss = new ServerSocket(10000); //2.等待客户端来连接 Socket socket = ss.accept(); //3.读取数据并保存到本地文件中 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); String name = UUID.randomUUID().toString().replace("-", ""); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("mysocketnet\\serverdir\\" + name + ".jpg")); int len; byte[] bytes = new byte[1024]; while ((len = bis.read(bytes)) != -1) { bos.write(bytes, 0, len); } bos.close(); //4.回写数据 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bw.write("上传成功"); bw.newLine(); bw.flush(); //5.释放资源 socket.close(); ss.close(); } }
练习五:服务器改写为多线程
服务器只能处理一个客户端请求,接收完一个图片之后,服务器就关闭了。
优化方案一:
使用循环
弊端:
第一个用户正在上传数据,第二个用户就来访问了,此时第二个用户是无法成功上传的。
所以,使用多线程改进
优化方案二:
每来一个用户,就开启多线程处理
public class Client { public static void main(String[] args) throws IOException { //客户端:将本地文件上传到服务器。接收服务器的反馈。 //服务器:接收客户端上传的文件,上传完毕之后给出反馈。 //1. 创建Socket对象,并连接服务器 Socket socket = new Socket("127.0.0.1",10000); //2.读取本地文件中的数据,并写到服务器当中 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("mysocketnet\\clientdir\\a.jpg")); BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); byte[] bytes = new byte[1024]; int len; while ((len = bis.read(bytes)) != -1){ bos.write(bytes,0,len); } //往服务器写出结束标记 socket.shutdownOutput(); //3.接收服务器的回写数据 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = br.readLine(); System.out.println(line); //4.释放资源 socket.close(); } } public class Server { public static void main(String[] args) throws IOException { //客户端:将本地文件上传到服务器。接收服务器的反馈。 //服务器:接收客户端上传的文件,上传完毕之后给出反馈。 //1.创建对象并绑定端口 ServerSocket ss = new ServerSocket(10000); while (true) { //2.等待客户端来连接 Socket socket = ss.accept(); //开启一条线程 //一个用户就对应服务端的一条线程 new Thread(new MyRunnable(socket)).start(); } } } public class MyRunnable implements Runnable{ Socket socket; public MyRunnable(Socket socket){ this.socket = socket; } @Override public void run() { try { //3.读取数据并保存到本地文件中 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); String name = UUID.randomUUID().toString().replace("-", ""); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("mysocketnet\\serverdir\\" + name + ".jpg")); int len; byte[] bytes = new byte[1024]; while ((len = bis.read(bytes)) != -1) { bos.write(bytes, 0, len); } bos.close(); //4.回写数据 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bw.write("上传成功"); bw.newLine(); bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { //5.释放资源 if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
练习六:线程池改进
public class Client { public static void main(String[] args) throws IOException { //客户端:将本地文件上传到服务器。接收服务器的反馈。 //服务器:接收客户端上传的文件,上传完毕之后给出反馈。 //1. 创建Socket对象,并连接服务器 Socket socket = new Socket("127.0.0.1",10000); //2.读取本地文件中的数据,并写到服务器当中 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("mysocketnet\\clientdir\\a.jpg")); BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); byte[] bytes = new byte[1024]; int len; while ((len = bis.read(bytes)) != -1){ bos.write(bytes,0,len); } //往服务器写出结束标记 socket.shutdownOutput(); //3.接收服务器的回写数据 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = br.readLine(); System.out.println(line); //4.释放资源 socket.close(); } } public class Server { public static void main(String[] args) throws IOException { //客户端:将本地文件上传到服务器。接收服务器的反馈。 //服务器:接收客户端上传的文件,上传完毕之后给出反馈。 //创建线程池对象 ThreadPoolExecutor pool = new ThreadPoolExecutor( 3,//核心线程数量 16,//线程池总大小 60,//空闲时间 TimeUnit.SECONDS,//空闲时间(单位) new ArrayBlockingQueue<>(2),//队列 Executors.defaultThreadFactory(),//线程工厂,让线程池如何创建线程对象 new ThreadPoolExecutor.AbortPolicy()//阻塞队列 ); //1.创建对象并绑定端口 ServerSocket ss = new ServerSocket(10000); while (true) { //2.等待客户端来连接 Socket socket = ss.accept(); //开启一条线程 //一个用户就对应服务端的一条线程 //new Thread(new MyRunnable(socket)).start(); pool.submit(new MyRunnable(socket)); } } } public class MyRunnable implements Runnable{ Socket socket; public MyRunnable(Socket socket){ this.socket = socket; } @Override public void run() { try { //3.读取数据并保存到本地文件中 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); String name = UUID.randomUUID().toString().replace("-", ""); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("mysocketnet\\serverdir\\" + name + ".jpg")); int len; byte[] bytes = new byte[1024]; while ((len = bis.read(bytes)) != -1) { bos.write(bytes, 0, len); } bos.close(); //4.回写数据 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bw.write("上传成功"); bw.newLine(); bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { //5.释放资源 if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }