Java基于Socket文件传输示例

jopen 11年前

需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解。在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度。废话少说,先来看服务器端的程序。
1.服务器端

import  java.io.BufferedInputStream;  import  java.io.DataInputStream;  import  java.io.DataOutputStream;  import  java.io.File;  import  java.io.FileInputStream;  import  java.net.ServerSocket;  import  java.net.Socket;    public   class  ServerTest  {       int  port  =   8821 ;         void  start()  {          Socket s  =   null ;           try   {              ServerSocket ss  =   new  ServerSocket(port);               while  ( true )  {                   //  选择进行传输的文件                  String filePath  =   " D://lib.rar " ;                  File fi  =   new  File(filePath);                    System.out.println( " 文件长度: "   +  ( int ) fi.length());                     //  public Socket accept() throws                   //  IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。                    s  =  ss.accept();                  System.out.println( " 建立socket链接 " );                  DataInputStream dis  =   new  DataInputStream( new  BufferedInputStream(s.getInputStream()));                  dis.readByte();                    DataInputStream fis  =   new  DataInputStream( new  BufferedInputStream( new  FileInputStream(filePath)));                  DataOutputStream ps  =   new  DataOutputStream(s.getOutputStream());                   // 将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java 4th里有现成的代码。                  ps.writeUTF(fi.getName());                  ps.flush();                  ps.writeLong(( long ) fi.length());                  ps.flush();                     int  bufferSize  =   8192 ;                   byte [] buf  =   new   byte [bufferSize];                     while  ( true )  {                       int  read  =   0 ;                       if  (fis  !=   null )  {                          read  =  fis.read(buf);                      }                         if  (read  ==   - 1 )  {                           break ;                      }                      ps.write(buf,  0 , read);                  }                  ps.flush();                   //  注意关闭socket链接哦,不然客户端会等待server的数据过来,                   //  直到socket超时,导致数据不完整。                                  fis.close();                  s.close();                                  System.out.println( " 文件传输完成 " );              }            }   catch  (Exception e)  {              e.printStackTrace();          }      }         public   static   void  main(String arg[])  {           new  ServerTest().start();      }  }
2.socket的Util辅助类
 import  java.net. * ;  import  java.io. * ;    public   class  ClientSocket  {       private  String ip;         private   int  port;         private  Socket socket  =   null ;        DataOutputStream out  =   null ;        DataInputStream getMessageStream  =   null ;         public  ClientSocket(String ip,  int  port)  {           this .ip  =  ip;           this .port  =  port;      }         /**       * 创建socket连接       *        *  @throws  Exception       *             exception        */       public   void  CreateConnection()  throws  Exception  {           try   {              socket  =   new  Socket(ip, port);          }   catch  (Exception e)  {              e.printStackTrace();               if  (socket  !=   null )                  socket.close();               throw  e;          }   finally   {          }      }         public   void  sendMessage(String sendMessage)  throws  Exception  {           try   {              out  =   new  DataOutputStream(socket.getOutputStream());               if  (sendMessage.equals( " Windows " ))  {                  out.writeByte( 0x1 );                  out.flush();                   return ;              }               if  (sendMessage.equals( " Unix " ))  {                  out.writeByte( 0x2 );                  out.flush();                   return ;              }               if  (sendMessage.equals( " Linux " ))  {                  out.writeByte( 0x3 );                  out.flush();              }   else   {                  out.writeUTF(sendMessage);                  out.flush();              }          }   catch  (Exception e)  {              e.printStackTrace();               if  (out  !=   null )                  out.close();               throw  e;          }   finally   {          }      }         public  DataInputStream getMessageStream()  throws  Exception  {           try   {              getMessageStream  =   new  DataInputStream( new  BufferedInputStream(socket.getInputStream()));               return  getMessageStream;          }   catch  (Exception e)  {              e.printStackTrace();               if  (getMessageStream  !=   null )                  getMessageStream.close();               throw  e;          }   finally   {          }      }         public   void  shutDownConnection()  {           try   {               if  (out  !=   null )                  out.close();               if  (getMessageStream  !=   null )                  getMessageStream.close();               if  (socket  !=   null )                  socket.close();          }   catch  (Exception e)  {            }      }  }
3.客户端
 import  java.io.BufferedOutputStream;  import  java.io.DataInputStream;  import  java.io.DataOutputStream;  import  java.io.FileOutputStream;    public   class  ClientTest  {       private  ClientSocket cs  =   null ;         private  String ip  =   " localhost " ; //  设置成服务器IP         private   int  port  =   8821 ;         private  String sendMessage  =   " Windwos " ;         public  ClientTest()  {           try   {               if  (createConnection())  {                  sendMessage();                  getMessage();              }            }   catch  (Exception ex)  {              ex.printStackTrace();          }      }         private   boolean  createConnection()  {          cs  =   new  ClientSocket(ip, port);           try   {              cs.CreateConnection();              System.out.print( " 连接服务器成功! "   +   " /n " );               return   true ;          }   catch  (Exception e)  {              System.out.print( " 连接服务器失败! "   +   " /n " );               return   false ;          }        }         private   void  sendMessage()  {           if  (cs  ==   null )               return ;           try   {              cs.sendMessage(sendMessage);          }   catch  (Exception e)  {              System.out.print( " 发送消息失败! "   +   " /n " );          }      }         private   void  getMessage()  {           if  (cs  ==   null )               return ;          DataInputStream inputStream  =   null ;           try   {              inputStream  =  cs.getMessageStream();          }   catch  (Exception e)  {              System.out.print( " 接收消息缓存错误/n " );               return ;          }             try   {               // 本地保存路径,文件名会自动从服务器端继承而来。              String savePath  =   " E:// " ;               int  bufferSize  =   8192 ;               byte [] buf  =   new   byte [bufferSize];               int  passedlen  =   0 ;               long  len = 0 ;                            savePath  +=  inputStream.readUTF();              DataOutputStream fileOut  =   new  DataOutputStream( new  BufferedOutputStream( new  BufferedOutputStream( new  FileOutputStream(savePath))));              len  =  inputStream.readLong();                            System.out.println( " 文件的长度为: "   +  len  +   " /n " );              System.out.println( " 开始接收文件! "   +   " /n " );                                     while  ( true )  {                   int  read  =   0 ;                   if  (inputStream  !=   null )  {                      read  =  inputStream.read(buf);                  }                  passedlen  +=  read;                   if  (read  ==   - 1 )  {                       break ;                  }                   // 下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比                  System.out.println( " 文件接收了 "   +   (passedlen  *   100 /  len)  +   " %/n " );                  fileOut.write(buf,  0 , read);              }              System.out.println( " 接收完成,文件存为 "   +  savePath  +   " /n " );                fileOut.close();          }   catch  (Exception e)  {              System.out.println( " 接收消息错误 "   +   " /n " );               return ;          }      }         public   static   void  main(String arg[])  {           new  ClientTest();      }  } 

这就实现了从服务器端向客户端发送文件的过程,当然,反过来,也一样.稍有不同.代码中对跨平台的细节没有实现,