java socket文件上传 转之 http://blog.csdn.net/huang930528/article/details/52401565

客户端设计思路:客户端与服务端建立连接,选择客户端本地文件,先将文件名及大小等属性发送给服务端,再将文件通过流的方式传输给服务端。传输的进度打印到控制台中,直到传输完成。

服务端设计思路:服务端接收客户端的请求(阻塞式),每接收到一个客户端请求连接后,就新开一个处理文件的线程,开始写入流,将文件到服务器的指定目录下,并与传输过来的文件同名。


客户端代码:

[java]  view plain  copy
  1. import java.io.DataOutputStream;  
  2. import java.io.File;  
  3. import java.io.FileInputStream;  
  4. import java.net.Socket;  
  5.   
  6. /** 
  7.  * 文件传输Client端<br> 
  8.  * 功能说明: 
  9.  * 
  10.  * @author 大智若愚的小懂 
  11.  * @Date 2016年09月01日 
  12.  * @version 1.0 
  13.  */  
  14. public class FileTransferClient extends Socket {  
  15.   
  16.     private static final String SERVER_IP = "127.0.0.1"// 服务端IP  
  17.     private static final int SERVER_PORT = 8899// 服务端端口  
  18.   
  19.     private Socket client;  
  20.   
  21.     private FileInputStream fis;  
  22.   
  23.     private DataOutputStream dos;  
  24.   
  25.     /** 
  26.      * 构造函数<br/> 
  27.      * 与服务器建立连接 
  28.      * @throws Exception 
  29.      */  
  30.     public FileTransferClient() throws Exception {  
  31.         super(SERVER_IP, SERVER_PORT);  
  32.         this.client = this;  
  33.         System.out.println("Cliect[port:" + client.getLocalPort() + "] 成功连接服务端");  
  34.     }  
  35.   
  36.     /** 
  37.      * 向服务端传输文件 
  38.      * @throws Exception 
  39.      */  
  40.     public void sendFile() throws Exception {  
  41.         try {  
  42.             File file = new File("E:\\JDK1.6中文参考手册(JDK_API_1_6_zh_CN).CHM");  
  43.             if(file.exists()) {  
  44.                 fis = new FileInputStream(file);  
  45.                 dos = new DataOutputStream(client.getOutputStream());  
  46.   
  47.                 // 文件名和长度  
  48.                 dos.writeUTF(file.getName());  
  49.                 dos.flush();  
  50.                 dos.writeLong(file.length());  
  51.                 dos.flush();  
  52.   
  53.                 // 开始传输文件  
  54.                 System.out.println("======== 开始传输文件 ========");  
  55.                 byte[] bytes = new byte[1024];  
  56.                 int length = 0;  
  57.                 long progress = 0;  
  58.                 while((length = fis.read(bytes, 0, bytes.length)) != -1) {  
  59.                     dos.write(bytes, 0, length);  
  60.                     dos.flush();  
  61.                     progress += length;  
  62.                     System.out.print("| " + (100*progress/file.length()) + "% |");  
  63.                 }  
  64.                 System.out.println();  
  65.                 System.out.println("======== 文件传输成功 ========");  
  66.             }  
  67.         } catch (Exception e) {  
  68.             e.printStackTrace();  
  69.         } finally {  
  70.             if(fis != null)  
  71.                 fis.close();  
  72.             if(dos != null)  
  73.                 dos.close();  
  74.             client.close();  
  75.         }  
  76.     }  
  77.   
  78.     /** 
  79.      * 入口 
  80.      * @param args 
  81.      */  
  82.     public static void main(String[] args) {  
  83.         try {  
  84.             FileTransferClient client = new FileTransferClient(); // 启动客户端连接  
  85.             client.sendFile(); // 传输文件  
  86.         } catch (Exception e) {  
  87.             e.printStackTrace();  
  88.         }  
  89.     }  
  90.   
  91. }  

服务端代码:

[java]  view plain  copy
  1. import java.io.DataInputStream;  
  2. import java.io.File;  
  3. import java.io.FileOutputStream;  
  4. import java.math.RoundingMode;  
  5. import java.net.ServerSocket;  
  6. import java.net.Socket;  
  7. import java.text.DecimalFormat;  
  8.   
  9. /** 
  10.  * 文件传输Server端<br> 
  11.  * 功能说明: 
  12.  * 
  13.  * @author 大智若愚的小懂 
  14.  * @Date 2016年09月01日 
  15.  * @version 1.0 
  16.  */  
  17. public class FileTransferServer extends ServerSocket {  
  18.   
  19.     private static final int SERVER_PORT = 8899// 服务端端口  
  20.   
  21.     private static DecimalFormat df = null;  
  22.   
  23.     static {  
  24.         // 设置数字格式,保留一位有效小数  
  25.         df = new DecimalFormat("#0.0");  
  26.         df.setRoundingMode(RoundingMode.HALF_UP);  
  27.         df.setMinimumFractionDigits(1);  
  28.         df.setMaximumFractionDigits(1);  
  29.     }  
  30.   
  31.     public FileTransferServer() throws Exception {  
  32.         super(SERVER_PORT);  
  33.     }  
  34.   
  35.     /** 
  36.      * 使用线程处理每个客户端传输的文件 
  37.      * @throws Exception 
  38.      */  
  39.     public void load() throws Exception {  
  40.         while (true) {  
  41.             // server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的  
  42.             Socket socket = this.accept();  
  43.             /** 
  44.              * 我们的服务端处理客户端的连接请求是同步进行的, 每次接收到来自客户端的连接请求后, 
  45.              * 都要先跟当前的客户端通信完之后才能再处理下一个连接请求。 这在并发比较多的情况下会严重影响程序的性能, 
  46.              * 为此,我们可以把它改为如下这种异步处理与客户端通信的方式 
  47.              */  
  48.             // 每接收到一个Socket就建立一个新的线程来处理它  
  49.             new Thread(new Task(socket)).start();  
  50.         }  
  51.     }  
  52.   
  53.     /** 
  54.      * 处理客户端传输过来的文件线程类 
  55.      */  
  56.     class Task implements Runnable {  
  57.   
  58.         private Socket socket;  
  59.   
  60.         private DataInputStream dis;  
  61.   
  62.         private FileOutputStream fos;  
  63.   
  64.         public Task(Socket socket) {  
  65.             this.socket = socket;  
  66.         }  
  67.   
  68.         @Override  
  69.         public void run() {  
  70.             try {  
  71.                 dis = new DataInputStream(socket.getInputStream());  
  72.   
  73.                 // 文件名和长度  
  74.                 String fileName = dis.readUTF();  
  75.                 long fileLength = dis.readLong();  
  76.                 File directory = new File("D:\\FTCache");  
  77.                 if(!directory.exists()) {  
  78.                     directory.mkdir();  
  79.                 }  
  80.                 File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);  
  81.                 fos = new FileOutputStream(file);  
  82.   
  83.                 // 开始接收文件  
  84.                 byte[] bytes = new byte[1024];  
  85.                 int length = 0;  
  86.                 while((length = dis.read(bytes, 0, bytes.length)) != -1) {  
  87.                     fos.write(bytes, 0, length);  
  88.                     fos.flush();  
  89.                 }  
  90.                 System.out.println("======== 文件接收成功 [File Name:" + fileName + "] [Size:" + getFormatFileSize(fileLength) + "] ========");  
  91.             } catch (Exception e) {  
  92.                 e.printStackTrace();  
  93.             } finally {  
  94.                 try {  
  95.                     if(fos != null)  
  96.                         fos.close();  
  97.                     if(dis != null)  
  98.                         dis.close();  
  99.                     socket.close();  
  100.                 } catch (Exception e) {}  
  101.             }  
  102.         }  
  103.     }  
  104.   
  105.     /** 
  106.      * 格式化文件大小 
  107.      * @param length 
  108.      * @return 
  109.      */  
  110.     private String getFormatFileSize(long length) {  
  111.         double size = ((double) length) / (1 << 30);  
  112.         if(size >= 1) {  
  113.             return df.format(size) + "GB";  
  114.         }  
  115.         size = ((double) length) / (1 << 20);  
  116.         if(size >= 1) {  
  117.             return df.format(size) + "MB";  
  118.         }  
  119.         size = ((double) length) / (1 << 10);  
  120.         if(size >= 1) {  
  121.             return df.format(size) + "KB";  
  122.         }  
  123.         return length + "B";  
  124.     }  
  125.   
  126.     /** 
  127.      * 入口 
  128.      * @param args 
  129.      */  
  130.     public static void main(String[] args) {  
  131.         try {  
  132.             FileTransferServer server = new FileTransferServer(); // 启动服务端  
  133.             server.load();  
  134.         } catch (Exception e) {  
  135.             e.printStackTrace();  
  136.         }  
  137.     }  
  138. }  

测试的结果(客户端):


测试的结果(服务端):




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值