• Socket网络编程练习题五:客户端多用户上传文件(多线程版)并使用线程池管理线程


    题目

    想要服务器不停止,能接收很多客户上传的图片?我们知道是使用循环加多线程的方案来解决,但是如果频繁的创建和销毁线程,是非常浪费系统资源的,那应该怎么办呢?

    解决方案

    采用线程池,来管理线程

    代码实战

    客户端代码
    package com.heima;
    
    import java.io.*;
    import java.net.Socket;
    
    public class Client {
        public static void main(String[] args) throws IOException {
            Socket socket = new Socket("127.0.0.1",10000);
    
            //读取本地文件中的数据,并写到服务器中
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("G:\\wjkwk\\clientdir\\123.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();
    
            //接收服务器返回的数据
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = br.readLine();
            System.out.println(line);
            socket.close();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    服务端代码
    package com.heima;
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    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()//阻塞队列
            );
            ServerSocket serverSocket = new ServerSocket(10000);
    
            while (true){
                //等待客户端来连接
                Socket socket = serverSocket.accept();
                //开启一个线程
                //一个用户就对应服务端的一条线程
    //            new Thread(new MyRunnable(socket)).start();
                //使用线程池
                pool.submit(new MyRunnable(socket));
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    package com.heima;
    
    import java.io.*;
    import java.net.Socket;
    import java.util.UUID;
    
    public class MyRunnable implements Runnable {
    
        Socket socket;
        public MyRunnable(Socket socket){
            this.socket = socket;
        }
        @Override
        public void run() {
    
            try {
                //读取客户端上传的文件并保存到本地
                BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
                String name = UUID.randomUUID().toString().replace("-", "");
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("G:\\wjkwk\\serverdir\\"+name+".jpg"));
                int len;
                byte[] bytes = new byte[1024];
                while ((len = bis.read(bytes)) != -1){
                    bos.write(bytes,0,len);
                }
                //回写数据
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                bw.write("上传成功");
                bw.newLine();
                bw.flush();
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //释放资源
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
  • 相关阅读:
    视频教程下载:用ChatGPT玩转海外抖音TikTok
    react源码分析:babel如何解析jsx
    【DevOps】搭建你的第一个 Docker 应用栈
    了解低压差稳压IC(LDO)及其在电池驱动设备中的意义
    电脑小白快来!这有电脑常见故障解决方法
    CMU15445 (Fall 2020) 数据库系统 Project#1 - Buffer Pool 详解
    设计模式的六大设计原则
    贪心算法——背包问题
    Discrete Mathematics and Its Applications 8th Edition 目录
    Dockerfile文件详解
  • 原文地址:https://blog.csdn.net/weixin_43860634/article/details/133426010