java多線程文件上傳服務器

 

 描述:html

(1)jdk自帶線程池見 JDK自帶線程池配置java

(2)此上傳文件服務器中上傳文件的後綴名經過第一段緩衝字符流傳遞,此緩衝字符流大小爲1024,在文件接收端以1024接收、處理。服務器

 

 

一、服務器代碼以下(使用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 }

 

 

二、上傳文件代碼以下:多線程

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();

	
		
	}
}

 

 

三、接收文件代碼以下:socket

 

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();

        }

    }
}
相關文章
相關標籤/搜索