首页 > 代码库 > java多线程文件上传服务器

java多线程文件上传服务器

 

 描述:

(1)jdk自带线程池见 JDK自带线程池配置

(2)此上传文件服务器中上传文件的后缀名通过第一段缓冲字符流传递,此缓冲字符流大小为1024,在文件接收端以1024接收、处理。

 

 

1、服务器代码如下(使用jdk自带线程池):

 1 /**
 2  * 服务器处理多线程问题
 3  * 
 4  * 1.因为服务器是要很多人访问的,因此里面一定要用多线程来处理,不然只能一个人一个人的访问,那还叫Y啥服务器
 5  * 
 6  * 2,拿上面这个文件上传的例子来说,它将每个连接它的用户封装到线程里面去,把用户要执行的操作定义到 run 方法里面
 7  * 一个用户拿一个线程,拿到线程的就自己去执行,如果有其它用户来的时候,再给新来的用户分配一个新的线程 这样就完成了服务器处理多线程的问题 3.
 8  * 在服务器与客户端互传数据时,我们要特别注意的是,防止两个程序造成 死等的状态,一般原因有以下:
 9  * 
10  * 1. 客户端向数据端发送数据时,当发送的是字符时,第次以一行来发送,而服务端在读取的时候,也是以 一行来读取,readLine()
11  * 而发送的时候往往只是发送换行以行的内容,而不能发换行也发送过去, 那么服务端在读取的时候就不读取不到换行 ,那么 readLine() 就不会停止 2.
12  * 客户端发送数据时,如果处理的是用 字符流 或是缓冲流的话,一定要记得刷新流,不然的话,数据就会发不出来 3 在用IO 读取文件里面的数据然后发送到服务端
13  * 时,当家读取文件 while(in.read()) 读取文件结束时,而在 服务端的接收程序
14  * while(sin.read())不会接到一个发送完毕的提示,所以会一直等待下去,所以我们在处理这
15  * 个问题的时候,还要将其发送一个文件读取结束的标志,告诉接收端文件已经读取完结,不要再等待了 而socket 里面给我们封装了 shutdownInput
16  * shutdownOutput 两个操作,此可以关闭 流,两样也可以起到告诉 接收方文件传送完毕的效果
17  * 
18  * 
19  * 
20  * */
21 public class Server {
22     
23     private static Logger logger = LoggerFactory.getLogger(Server.class);
24     private static final Integer PORT = 2222;
25     
26 
27     public static void main(String args[]) throws Exception {
28 
29         ServerSocket server = new ServerSocket(PORT);
30         
31         logger.info("服务器启动:::端口号为:{}",PORT);
32         ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 300, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(3),
33                 new ThreadPoolExecutor.CallerRunsPolicy());
34         
35         while (true) {
36             
37             Socket client = server.accept();
38             executor.execute(new UploadThread(client));
39 //            new Thread(new UploadThread(client)).start();
40         }
41 
42     }
43 }

 

 

2、上传文件代码如下:

?
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package cn.iautos.manager.test.load;
 
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;
 
public class Upload {
     
    public static void main(String args[]) throws Exception {
         
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                try {
                    System.out.println("--------开始上传文件-------");
                    loadMethod();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 0, 500);
    }
     
    public static void loadMethod() throws Exception{
 
        String name = "E:\\qqq.jpg";
        Socket client = new Socket("127.0.0.1", 2222);
        File file = new File(name);
         
        String imgSuffix = ImgUtils.getImgSuffix(name);
         
        BufferedInputStream fin = new BufferedInputStream(new FileInputStream(
                file)); // 文件读取流
        PrintStream sout = new PrintStream(client.getOutputStream(), true); // 得到socket流
        /**
         * 添加后缀名
         */
        byte[] b = new byte[1024];
            byte[] bb = (imgSuffix+"\n").getBytes();
            for(int j = 0;j<bb.length;j++){
                b[j] = bb[j];
            }
        sout.write(b,0,b.length);
         
        int len = 0;
        while ((len = fin.read(b)) != -1) {
            sout.write(b, 0, len);
            System.out.println(len + "...发送中");
        }
        client.shutdownOutput();
        BufferedInputStream sin = new BufferedInputStream(client
                .getInputStream());
        len = sin.read(b);
        System.out.println(len);
        System.out.println(new String(b, 0, len));
        sin.close();
        sout.close();
        fin.close();
 
     
         
    }
}

 

 

3、接收文件代码如下:

 

package cn.iautos.manager.test.load;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class UploadThread implements Runnable // 将上传封装到线程里
{
    private Socket client;

    public UploadThread(Socket s) {
        this.client = s;
    }

    public void run() {
//        String ip = client.getInetAddress().getHostAddress(); // 得到 IP地址
        try {
            BufferedInputStream sin = new BufferedInputStream(client.getInputStream()); // Socket 读取流
            byte b[] = new byte[1024];
            int l = sin.read(b);
            String line = new String(b, 0, l).split("\n")[0];
            System.out.println("--------文件后缀为------"+line);
            
            File file = new File("E:\\loadServer\\" + ImgUtils.getImgName()
                    + line);
            BufferedOutputStream fout = new BufferedOutputStream(
                    new FileOutputStream(file)); // 文件输出流
            
            int len = 0;
            // 开始从网络中读取数据
            while (true) {
                len = sin.read(b);
                if(len != -1){
                    fout.write(b, 0, len);
                }else{
                    break;
                }
//                System.out.println("--------------"+new String(buf,0,len));
            }
            PrintStream sout = new PrintStream(client.getOutputStream());
            sout.write("发送成功".getBytes());
            // sout.flush(); //虽然是字节流,但其用的是BufferedOutputStream
            fout.close();
            sin.close();
            sout.close();
        } catch (Exception ex) {
            System.out.println();
            ex.printStackTrace();

        }

    }
}