代码改变世界

Java基于Socket文件传输示例

2011-04-29 10:59  myjava2  阅读(193)  评论(0编辑  收藏  举报

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

1.服务器端

package  sterning;

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辅助类

package  sterning;

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.客户端

package  sterning;

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

}


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