需求:每一个客户端启动后都可以给服务器上传一个文件,服务器接收到文件后保存到一个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/12291766.html
时间: 2024-10-09 06:38:56