Java基于Socket文件傳輸示例

jopen 10年前發布 | 25K 次閱讀 Socket Java開發

需要進行網絡傳輸大文件,于是對基于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();
}

}</pre> 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)  {

    }
}

}</pre>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();
}

} </pre>
這就實現了從服務器端向客戶端發送文件的過程,當然,反過來,也一樣.稍有不同.代碼中對跨平臺的細節沒有實現,

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!