Java 网络编程:(十一)案例三:多台客户端上传文件

  需求:每一个客户端启动后都可以给服务器上传一个文件,服务器接收到文件后保存到一个upload目录中。可以同时接收多个客户端的文件上传。

  分析:

  (1)服务器端要“同时”处理多个客户端的请求,那么必须使用多线程,每一个客户端的通信需要单独的线程来处理。

  (2)服务器保存上传文件的目录只有一个upload,而每个客户端给服务器发送的文件可能重名,所以需要保证文件名的唯一。我们可以使用“时间戳”作为文件名,而后缀名不变

  (3)客户端需要给服务器上传文件名(含后缀名)以及文件内容。而文件名是字符串,文件内容不一定是纯文本的,因此选择DataOutputStream和DataInputStream。

  客户端的实例代码:

 1 import java.io.BufferedReader;
 2 import java.io.DataOutputStream;
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.InputStream;
 6 import java.io.InputStreamReader;
 7 import java.io.OutputStream;
 8 import java.net.Socket;
 9 import java.util.Scanner;
10 
11 public class Client {
12     public static void main(String[] args) throws Exception {
13         // (1)连接服务器
14         Socket socket = new Socket("192.168.54.68", 8888);
15 
16         Scanner input = new Scanner(System.in);
17         
18         //(2)从键盘输入文件的路径和名称
19         System.out.print("请选择要上传的文件:");
20         String path = input.nextLine();
21         File file = new File(path);
22         
23         OutputStream out = socket.getOutputStream();
24         DataOutputStream dos = new DataOutputStream(out);//用它的目的是为了既可以单独传一个字符串,又可以写字节内容
25         
26         //先发送文件名(含后缀名)
27         dos.writeUTF(file.getName());//单独发一个字符串
28         
29         //还需要一个IO流,从文件读取内容,给服务器发过去
30         FileInputStream fis = new FileInputStream(file);
31                 
32         //(3)把文件内容给服务器传过去,类似与复制文件
33         byte[] data = new byte[1024];
34         while(true){
35             int len = fis.read(data);
36             if(len==-1){
37                 break;
38             }
39             dos.write(data, 0, len);
40         }
41         socket.shutdownOutput();
42         
43         //(4)接收服务器返回的结果
44         InputStream is = socket.getInputStream();
45         InputStreamReader isr = new InputStreamReader(is);//把字节流转成字符流
46         BufferedReader br = new BufferedReader(isr);
47         String result = br.readLine();
48         System.out.println(result);
49         
50         //(5)关闭
51         fis.close();
52         input.close();
53         socket.close();
54     }
55 }

服务器端的实例代码

 1 import java.net.ServerSocket;
 2 import java.net.Socket;
 3 
 4 public class Server {
 5     public static void main(String[] args) throws Exception{
 6         //服务器在8888端口号监听数据
 7         @SuppressWarnings("resource")
 8         ServerSocket server = new ServerSocket(8888);
 9         
10         while(true){
11             //(2)等待连接 
12             //这句代码执行一次,意味着一个客户端连接
13             Socket accept = server.accept();
14         
15             FileUploadThread ft = new FileUploadThread(accept);
16             ft.start();
17         }
18     }
19 }

服务器端处理每一个客户端上传文件的线程类代码:

 1 import java.io.DataInputStream;
 2 import java.io.FileNotFoundException;
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.io.OutputStream;
 7 import java.io.PrintStream;
 8 import java.net.Socket;
 9 import java.text.SimpleDateFormat;
10 import java.util.Date;
11 
12 public class FileUploadThread extends Thread{
13     private Socket socket;
14     private String dir = "upload/";
15 
16     public FileUploadThread(Socket socket) {
17         super();
18         this.socket = socket;
19     }
20     
21     public void run(){
22         FileOutputStream fos = null;
23         try {
24             InputStream is = socket.getInputStream();
25             DataInputStream dis = new DataInputStream(is);    
26             
27             //读取文件名(含后缀名)
28             String filename = dis.readUTF();
29             //截取后缀名
30             String ext = filename.substring(filename.lastIndexOf("."));
31             //生成时间戳
32             SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
33             filename = sf.format(new Date());
34             //用新文件路径构建文件输出流
35             fos = new FileOutputStream(dir + filename + ext);
36             //接收文件内容
37             byte[] data = new byte[1024];
38             while(true){
39                 int len = is.read(data);
40                 if(len==-1){
41                     break;
42                 }
43                 fos.write(data, 0, len);
44             }
45             
46             //返回结果
47             OutputStream out = socket.getOutputStream();
48             PrintStream ps = new PrintStream(out);
49             ps.println(filename + ext + ":已上传完毕");
50         } catch (FileNotFoundException e) {
51             e.printStackTrace();
52         } catch (IOException e) {
53             e.printStackTrace();
54         }finally{
55             try {
56                 fos.close();
57                 socket.close();
58             } catch (IOException e) {
59                 e.printStackTrace();
60             }
61         }
62     }
63 }
原文地址:https://www.cnblogs.com/niujifei/p/14879943.html