Java基于Socket文件传输示例

                                   这是在网上看到的一个案例,为便于学习,特将此留于我的博客之上,非原创!如若有时间,必将此改善之!

基于socket的文件传输作了一个初步的了解,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度,

服务器端的程序如下:

 1 import java.io.BufferedInputStream;
 2 import java.io.DataInputStream;
 3 import java.io.DataOutputStream;
 4 import java.io.File;
 5 import java.io.FileInputStream;
 6 import java.net.ServerSocket;
 7 import java.net.Socket;
 8 
 9 public class ServerTest {
10     int port = 8821;
11 
12     void start() {
13         Socket s = null;
14         try {
15             ServerSocket ss = new ServerSocket(port);
16             while (true) {
17                 // 选择进行传输的文件
18                 String filePath = "D:\\lib.rar";
19                 File fi = new File(filePath);
20 
21                 System.out.println("文件长度:" + (int) fi.length());
22 
23                 // public Socket accept() throws
24                 // IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。
25 
26                 s = ss.accept();
27                 System.out.println("建立socket链接");
28                 DataInputStream dis = new DataInputStream(new BufferedInputStream(s.getInputStream()));
29                 dis.readByte();
30 
31                 DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
32                 DataOutputStream ps = new DataOutputStream(s.getOutputStream());
33                 //将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java 4th里有现成的代码。
34                 ps.writeUTF(fi.getName());
35                 ps.flush();
36                 ps.writeLong((long) fi.length());
37                 ps.flush();
38 
39                 int bufferSize = 8192;
40                 byte[] buf = new byte[bufferSize];
41 
42                 while (true) {
43                     int read = 0;
44                     if (fis != null) {
45                         read = fis.read(buf);
46                     }
47 
48                     if (read == -1) {
49                         break;
50                     }
51                     ps.write(buf, 0, read);
52                 }
53                 ps.flush();
54                 // 注意关闭socket链接哦,不然客户端会等待server的数据过来,
55                 // 直到socket超时,导致数据不完整。                
56                 fis.close();
57                 s.close();                
58                 System.out.println("文件传输完成");
59             }
60 
61         } catch (Exception e) {
62             e.printStackTrace();
63         }
64     }
65 
66     public static void main(String arg[]) {
67         new ServerTest().start();
68     }
69 }

socket的Util辅助类:

 1 public class ClientSocket {
 2     private String ip;
 3 
 4     private int port;
 5 
 6     private Socket socket = null;
 7 
 8     DataOutputStream out = null;
 9 
10     DataInputStream getMessageStream = null;
11 
12     public ClientSocket(String ip, int port) {
13         this.ip = ip;
14         this.port = port;
15     }
16 
17     /**
18      * 创建socket连接
19      * 
20      * @throws Exception
21      *             exception
22      */
23     public void CreateConnection() throws Exception {
24         try {
25             socket = new Socket(ip, port);
26         } catch (Exception e) {
27             e.printStackTrace();
28             if (socket != null)
29                 socket.close();
30             throw e;
31         } finally {
32         }
33     }
34 
35     public void sendMessage(String sendMessage) throws Exception {
36         try {
37             out = new DataOutputStream(socket.getOutputStream());
38             if (sendMessage.equals("Windows")) {
39                 out.writeByte(0x1);
40                 out.flush();
41                 return;
42             }
43             if (sendMessage.equals("Unix")) {
44                 out.writeByte(0x2);
45                 out.flush();
46                 return;
47             }
48             if (sendMessage.equals("Linux")) {
49                 out.writeByte(0x3);
50                 out.flush();
51             } else {
52                 out.writeUTF(sendMessage);
53                 out.flush();
54             }
55         } catch (Exception e) {
56             e.printStackTrace();
57             if (out != null)
58                 out.close();
59             throw e;
60         } finally {
61         }
62     }
63 
64     public DataInputStream getMessageStream() throws Exception {
65         try {
66             getMessageStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
67             return getMessageStream;
68         } catch (Exception e) {
69             e.printStackTrace();
70             if (getMessageStream != null)
71                 getMessageStream.close();
72             throw e;
73         } finally {
74         }
75     }
76 
77     public void shutDownConnection() {
78         try {
79             if (out != null)
80                 out.close();
81             if (getMessageStream != null)
82                 getMessageStream.close();
83             if (socket != null)
84                 socket.close();
85         } catch (Exception e) {
86 
87         }
88     }
89 }

客户端代码:

  1 import java.io.BufferedOutputStream;
  2 import java.io.DataInputStream;
  3 import java.io.DataOutputStream;
  4 import java.io.FileOutputStream;
  5 
  6 public class ClientTest {
  7     private ClientSocket cs = null;
  8 
  9     private String ip = "localhost";// 设置成服务器IP
 10 
 11     private int port = 8821;
 12 
 13     private String sendMessage = "Windwos";
 14 
 15     public ClientTest() {
 16         try {
 17             if (createConnection()) {
 18                 sendMessage();
 19                 getMessage();
 20             }
 21 
 22         } catch (Exception ex) {
 23             ex.printStackTrace();
 24         }
 25     }
 26 
 27     private boolean createConnection() {
 28         cs = new ClientSocket(ip, port);
 29         try {
 30             cs.CreateConnection();
 31             System.out.print("连接服务器成功!" + "\n");
 32             return true;
 33         } catch (Exception e) {
 34             System.out.print("连接服务器失败!" + "\n");
 35             return false;
 36         }
 37 
 38     }
 39 
 40     private void sendMessage() {
 41         if (cs == null)
 42             return;
 43         try {
 44             cs.sendMessage(sendMessage);
 45         } catch (Exception e) {
 46             System.out.print("发送消息失败!" + "\n");
 47         }
 48     }
 49 
 50     private void getMessage() {
 51         if (cs == null)
 52             return;
 53         DataInputStream inputStream = null;
 54         try {
 55             inputStream = cs.getMessageStream();
 56         } catch (Exception e) {
 57             System.out.print("接收消息缓存错误\n");
 58             return;
 59         }
 60 
 61         try {
 62             //本地保存路径,文件名会自动从服务器端继承而来。
 63             String savePath = "E:\\";
 64             int bufferSize = 8192;
 65             byte[] buf = new byte[bufferSize];
 66             int passedlen = 0;
 67             long len=0;
 68             
 69             savePath += inputStream.readUTF();
 70             DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream(savePath))));
 71             len = inputStream.readLong();
 72             
 73             System.out.println("文件的长度为:" + len + "\n");
 74             System.out.println("开始接收文件!" + "\n");
 75                     
 76             while (true) {
 77                 int read = 0;
 78                 if (inputStream != null) {
 79                     read = inputStream.read(buf);
 80                 }
 81                 passedlen += read;
 82                 if (read == -1) {
 83                     break;
 84                 }
 85                 //下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
 86                 System.out.println("文件接收了" +  (passedlen * 100/ len) + "%\n");
 87                 fileOut.write(buf, 0, read);
 88             }
 89             System.out.println("接收完成,文件存为" + savePath + "\n");
 90 
 91             fileOut.close();
 92         } catch (Exception e) {
 93             System.out.println("接收消息错误" + "\n");
 94             return;
 95         }
 96     }
 97 
 98     public static void main(String arg[]) {
 99         new ClientTest();
100     }
101 }

这就实现了从服务器端向客户端发送文件的过程,当然,反过来,也一样.稍有不同.代码中对跨平台的细节没有实现,有时间或兴趣的朋友可以提供一下.

posted @ 2015-07-19 16:20  Terminaling  阅读(344)  评论(0)    收藏  举报