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

浙公网安备 33010602011771号