JAVA 文件上传与下载

 

TCP协议,支持断点续传。

1、文件传输状态信息:FileState.java

/*
 * 创建日期 2008-12-28
 *
 * TODO 要更改此生成的文件的模板,请转至
 * 窗口 - 首选项 - Java - 代码样式 - 代码模板
 */
package com.myLink.tcp.client;

/**
 * @author Administrator
 *
 * TODO 要更改此生成的类型注释的模板,请转至
 * 窗口 - 首选项 - Java - 代码样式 - 代码模板
 */
public class FileState {
 private boolean isEnd=false;  //是否完成
 private int progress=0;   //进度,比如99%
 private long position=0;   //位置,即已完成字节数
 private String memo="";   //备注,比如传输失败,失败原因
 
 public boolean getIsEnd(){
  return isEnd;
 }
 public void setIsEnd(boolean v){
  isEnd=v;
 }
 
 public int getProgress(){
  return progress;
 }
 public void setProgress(int v){
  progress=v;
 }
 
 public long getPosition(){
  return position;
 }
 public void setPosition(long v){
  position=v;
 }

 /**
  * @return 返回 memo。
  */
 public String getMemo() {
  return memo;
 }
 /**
  * @param memo 要设置的 memo。
  */
 public void setMemo(String memo) {
  this.memo = memo;
 }
}

2、命令文件:CommonData.java


package com.myLink.common;

/**
 * 日期: 2006-7-29
 * 作者: 黄京亮
 * 描述: 共用的常量与变量
 * 参数:
 */
public class CommonData {

    /**================下面是常量================*/
    //标记结束符
    public static final String MYLINK_ENDCHAR=":MYLINK-ENDCHAR#";
    //请求文件名
    public static final String MYLINK_REQ_FILENAME="#MYLINK-REQ-FILENAME:";
    //文件名
    public static final String MYLINK_FILENAME="#MYLINK-FILENAME:";
    //文件长度
    public static final String MYLINK_LENGTH="#MYLINK-LENGTH:";
    //文件当前位置
    public static final String MYLINK_POSITION="#MYLINK-POSITION:";
    //输送完毕
    public static final String MYLINK_FINISH="#MYLINK-FINISH:";
    //继续传输
    public static final String MYLINK_NEXT="#MYLINK-NEXT:";
    //请求文件内容
    public static final String MYLINK_DATA="#MYLINK-DATA:";
    //准备就绪
    public static final String MYLINK_READY="#MYLINK-READY:";
    //错误:
    public static final String MYLINK_ERROR="#MYLINK-ERROR:";
    //下载命令
    public static final String MYLINK_CMD_DOWND="#MYLINK-CMD-DOWND:";
    //上传命令
    public static final String MYLINK_CMD_UP="#MYLINK-CMD-UP:";
    //端口号
    public static final int PORT=6789;
    //每一次传输的最大长度
    public static final int SEND_MAX_LEN=2048;
    //上传标识
    public static final int UPLOAD=1;
    //下载标识
    public static final int DOWNLOAD=2;
   
    /**================下面是变量================*/
   
}

3、客户端上传文件:ClientSender.java


package com.myLink.tcp.client;
import java.io.*;
import java.net.*;
import com.myLink.common.*;
/**
 * 日期: 2007-3-28
 * 作者: 黄京亮
 * 描述: 客户端发送上传
 * 参数:
 * 原理:
 * 0、服务端:监听socket端口;
 * 1、客户端:发出UP命令;
 * 2、服务端:收到命令后向客户端请求文件名;
 * 3、客户端:收到请求,发出文件名;
 * 4、服务端:收到文件名后检查本地是否已存在,并发出文件已接收到的大小(断点续传);
 * 5、客户端:收到断点传输位置后,先定位再发送,完毕。
 * 6、服务端:接收文件,完毕。
 */
public class ClientSender extends Thread
{
    private Socket socket;
    private String filename="";
    private long npost=0; //定义为当前位置
    private static final int MAX_LEN=CommonData.SEND_MAX_LEN;
   
 public ClientSender (Socket s)
 {
     this.socket=s;
 }

 public void run(){
 }
   
 public boolean send (int tcpGuid,String filename,FileState filestate)
 {
  this.filename =filename;

     try
        {
      //创建网络服务器接受客户请求
            Socket socket=this.socket;
            //创建网络接受流接受服务器文件数据
            InputStream netIn=socket.getInputStream();
            InputStream in=new DataInputStream(new BufferedInputStream(netIn));
            //创建网络输出流并提供数据包装器
            OutputStream netOut=socket.getOutputStream();
            OutputStream out=new DataOutputStream(new BufferedOutputStream(netOut));
           
            String stemp="";
            boolean isErrot=false;
            int num=0;
            //创建文件读取缓冲区
            byte[] buf=new byte[MAX_LEN];
            int len=0;
       
   File file=new File(filename);
   
   //检查文件是否存在
   if (file.exists()){
             //=========(1)========上传命令,含tcpGuid
             stemp=CommonData.MYLINK_CMD_UP+tcpGuid+CommonData.MYLINK_ENDCHAR;
             len=stemp.getBytes().length;
             buf=new byte[len];
             buf=stemp.getBytes();
             out.write(buf,0,buf.length);
             out.flush();
             System.out.println("1.>>>>>>>>>>发出上传命令:"+stemp);

             //=========(2)========响应服务端请求,发送文件名
             buf=new byte[MAX_LEN];
    num=in.read(buf);
    stemp=new String(buf,0,num,"gb2312");
    System.out.println("2.<<<<<<<<<<收到文件名请求:"+stemp);
    
    if (stemp.startsWith(CommonData.MYLINK_REQ_FILENAME)){
     stemp=CommonFun.getFileName(filename);
              stemp=CommonData.MYLINK_FILENAME+stemp+CommonData.MYLINK_ENDCHAR;
              len=stemp.getBytes().length;
              buf=new byte[len];
              buf=stemp.getBytes();
              out.write(buf,0,buf.length);
              out.flush();
             
              System.out.println("3.>>>>>>>>>>发出文件名:"+stemp);

             }else if (stemp.startsWith(CommonData.MYLINK_ERROR)){
             stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_ERROR);
            System.out.println("**********"+stemp);
            filestate.setMemo(stemp);
            isErrot=true;
            return false;
           }else{
            stemp="协议不对!";
            System.out.println("**********"+stemp);
            filestate.setMemo(stemp);
            //发送错误信号
                  stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                  len=stemp.getBytes().length;
                  buf=new byte[len];
                  buf=stemp.getBytes();
                  out.write(buf,0,buf.length);
                  out.flush();
                  isErrot=true;
            return false;
           }
    
    FileInputStream fos=new FileInputStream(file);
               
    if(isErrot){System.out.println("**********"+" 异常退出!");}
    else{
                 //==========(3)=========获取起始位置npost,并定位
        buf=new byte[MAX_LEN];
        num=in.read(buf);
        stemp=new String(buf,0,num,"gb2312");
        
        if (stemp.startsWith(CommonData.MYLINK_POSITION)){
                     stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_POSITION);
                     npost=Integer.parseInt(stemp);
                     System.out.println("4.<<<<<<<<<<收到断点定位:"+stemp);
                 }else if (stemp.startsWith(CommonData.MYLINK_ERROR)){
              stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_ERROR);
             System.out.println("**********"+stemp+" 异常退出!");
             filestate.setMemo(stemp);
             isErrot=true;
             return false;
            }else{
             stemp="协议不对,异常退出!";
             System.out.println("**********"+stemp);
             filestate.setMemo(stemp);
             //发送错误信号
                   stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                   len=stemp.getBytes().length;
                   buf=new byte[len];
                   buf=stemp.getBytes();
                   out.write(buf,0,buf.length);
                   out.flush();
                   isErrot=true;
             return false;
            }
    }

    if(isErrot){System.out.println("**********"+" 异常退出!");}
    else{
        //刷新文件状态
     long filesize=file.length();
     long totalnum=npost;
     int totalprog=(int)((totalnum/filesize)*100);
     filestate.setPosition(totalnum);
     
        //读文件前,先定位
        fos.skip(npost);
        
        System.out.println("==========开始发送数据");
     //==========(4)=========读出文件中的数据并发送
     buf=new byte[MAX_LEN];
        num=fos.read(buf);
        totalnum=totalnum+num;
        while(num!=(-1)){//是否读完文件
    
            out.write(buf,0,num);//把文件数据写出网络缓冲区
    
            out.flush();//刷新缓冲区把数据写往客户端
    
            num=fos.read(buf);//继续从文件中读取数据
            //刷新文件状态
            if(num!=(-1)){
             totalnum=totalnum+num;
             totalprog=(int)(totalnum*100/filesize);
             filestate.setPosition(totalnum);
             filestate.setProgress(totalprog);
             //System.out.println(totalprog);
            }
        }
        filestate.setIsEnd(true);//传输完毕
    }
    
             fos.close();
             System.out.println("==========上传完毕");
            }else{
                //文件不存在,发送错误消息
             stemp="客户端要上传的文件不存在!";
             System.out.println("**********"+stemp);
             filestate.setMemo("客户端要上传的文件不存在!");
             
                stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                len=stemp.getBytes().length;
                buf=new byte[len];
                buf=stemp.getBytes();
                out.write(buf,0,buf.length);
                out.flush();//刷新缓冲区把数据写往客户端

            }
   
   if(in!=null)in=null;
            if(out!=null)out=null;
            return true;
        }catch(IOException e)
        {
            e.printStackTrace();
            return false;
        }finally{
         try{
          socket.close();
         }catch(IOException e)
         {
                e.printStackTrace();
            }
         
        }
       
 }
}

 

4、服务端接收文件:ServerReceiver.java


package com.myLink.tcp.server;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.Socket;

import com.myLink.common.*;

/**
 * 日期: 2007-3-28
 * 作者: 黄京亮
 * 描述: 服务端接收
 * 参数:
 * 原理:
 * 0、服务端:监听socket端口;
 * 1、客户端:发出UP命令;
 * 2、服务端:收到命令后向客户端请求文件名;
 * 3、客户端:收到请求,发出文件名;
 * 4、服务端:收到文件名后检查本地是否已存在,并发出文件已接收到的大小(断点续传);
 * 5、客户端:收到断点传输位置后,先定位再发送,完毕。
 * 6、服务端:接收文件,完毕。
 */
public class ServerReceiver extends Thread
{
    private Socket socket;
    private String datapath="";
    private String filename="";
    private RandomAccessFile raf=null;
    private long npost=0;
    private boolean isReady=false;
    private Tcp tcp=null;
    private static final int MAX_LEN=CommonData.SEND_MAX_LEN ;
   
    public ServerReceiver(Socket s,Tcp tcp)
    {
        this.socket=s;
        this.tcp=tcp;
        this.filename =tcp.getFilePath()+tcp.getFileName();
    }
   
    public void run()
    {
        try{   

            //创建网络服务器接受客户请求
            Socket socket=this.socket;
            //创建网络接受流接受服务器文件数据
            InputStream netIn=socket.getInputStream();
            InputStream in=new DataInputStream(new BufferedInputStream(netIn));
            //创建网络输出流并提供数据包装器
            OutputStream netOut=socket.getOutputStream();
            OutputStream out=new DataOutputStream(new BufferedOutputStream(netOut));
           
            String stemp="";
            boolean isError=false;
            int num=0;
            //创建缓冲区缓冲网络数据
            byte[] buf=new byte[MAX_LEN];
            int len=0;
           
            //if(filename==null||filename==""||filename.equals("")){
             //(1)首先请求文件名
             stemp=CommonData.MYLINK_REQ_FILENAME;
             len=stemp.getBytes().length;
             buf=new byte[len];
             buf=stemp.getBytes();
             out.write(buf,0,buf.length);
             out.flush();
             System.out.println("1.>>>>>>>>>>请求文件名");
             //(2)接收文件名
             buf=new byte[MAX_LEN];
    num=in.read(buf);
    stemp=new String(buf,0,num,"gb2312");
    if (stemp.startsWith(CommonData.MYLINK_FILENAME)){
                 stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_FILENAME);
                 this.filename =stemp;
                 tcp.setFileName(CommonFun.getFileName(filename));
                 tcp.setFilePath(CommonFun.getFilePath(filename));
        //服务端接收文件所在路径
        datapath=CommonFun.getDataPath();
        if (!datapath.substring(1,2).equals(":")){
         datapath=CommonFun.getMainDir()+datapath;
        }
        System.out.println("2.<<<<<<<<<<收到文件名:"+filename);
        filename=datapath+CommonFun.getFileName(filename);
             }else if (stemp.startsWith(CommonData.MYLINK_ERROR)){
             stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_ERROR);
            System.out.println("**********"+stemp);
            isError=true;
           }else{
            stemp="协议不对!";
            System.out.println("**********"+stemp);

            //发送错误信号
                  stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                  len=stemp.getBytes().length;
                  buf=new byte[len];
                  buf=stemp.getBytes();
                  out.write(buf,0,buf.length);
                  out.flush();
                  isError=true;
           }
            //}
   
   if(isError){System.out.println("**********"+"异常退出");}
   else if (!filename.equals(null) && !filename.equals("")){
       File file=new File(filename);
            
             //检查本地是否已存在该文件
             if (file.exists()){
                 //已存在,则取其长度,以便告诉对方从哪个位置起传输
                 npost=file.length();
             }else{
                 //不存在,则创建本地空文件
              /**若路径不存在,则创建*/
           try{
            
            File filepath=new File(CommonFun.getFilePath(filename));
            if(!filepath.exists()){
             filepath.mkdirs();
            }
           }catch(Exception e){
            System.out.println("**********"+"创建文件路径失败");
           }

                 file.createNewFile();
                 npost=0;
             }
            
             //=========(3)========发送起始位置npost
             buf=new byte[MAX_LEN];
             stemp=CommonData.MYLINK_POSITION+npost+CommonData.MYLINK_ENDCHAR;
             len=stemp.getBytes().length;
                buf=new byte[len];
             buf=stemp.getBytes();
             out.write(buf,0,buf.length);
             out.flush();

             System.out.println("3.>>>>>>>>>>发出断点续传定位:"+stemp);
    //写入文件前,先定位
             raf=new RandomAccessFile(file,"rw");
             raf.seek(npost);
            
             System.out.println("=========开始接收数据");  
             //=========(4)========获取网络中的数据并写入文件  
    buf=new byte[MAX_LEN];
             num=in.read(buf);

             while(num!=(-1)){//是否读完所有数据

                    raf.write(buf,0,num);//将数据写往文件

                    raf.skipBytes(num);//顺序写文件字节

                    num=in.read(buf);//继续从网络中读取文件

             }
             System.out.println("==========接收完毕");  
             System.out.println("==========文件保存在:"+filename);  
             raf.close();
             tcp.setSuccess(true);//成功
   }else{
       stemp="客户端没有指定要上传的文件名!";
          System.out.println("*********"+stemp);

           //发送错误信号
                stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                len=stemp.getBytes().length;
                buf=new byte[len];
                buf=stemp.getBytes();
                out.write(buf,0,buf.length);
                out.flush();
   }

   if(in!=null)in=null;
            if(out!=null)out=null;
        }catch(IOException e)
        {
         try{
          raf.close();
         }catch(IOException e2)
         {
                //e2.printStackTrace();
          System.out.println("*********关闭文件出错/n"+e2.toString());
            }
         //e.printStackTrace();
         System.out.println("*********传输连接断开/n"+e.toString());
        }finally{
         try{
          tcp.setDoAlready(true);//已处理,里面调用了setChanged()
          tcp.notifyObservers(tcp);//====tcp.setDoAlready(true)里先调用setChanged();然后再通知
          socket.close();
         }catch(IOException e)
         {
                //e.printStackTrace();
          System.out.println("*********关闭socket出错/n"+e.toString());
            }
        }
    }
}

5、客户端下载文件:ClientReceiver.java


package com.myLink.tcp.client;

import java.io.*;
import java.net.*;
import com.myLink.common.*;

/**
 * 日期: 2007-3-28
 * 作者: 黄京亮
 * 描述: 客户端接收下载
 * 参数:
 * 原理:
 * 0、服务端:监听socket端口;
 * 1、客户端:发出DOWND命令;
 * 2、服务端:收到命令后向客户端请求文件名;
 * 3、客户端:收到请求,发出文件名;
 * 4、服务端:收到文件名后检查本地是否存在该文件,存在则发出文件大小
 * 5、客户端:收到文件大小后检查本地是否已存在,并发出文件已接收到的大小(断点续传);
 * 6、服务端:收到传输的起始位置后,先定位再发送,完毕。
 * 7、客户端:接收文件,完毕。
 */

public class ClientReceiver extends Thread
{
    private Socket socket;
    private String downfilename="";//要下载的文件名
    private String savefilename="";//要保存的文件名
    private long filesize=0;
    private long npost=0;
    private boolean isReady=false;
    private static final int MAX_LEN=CommonData.SEND_MAX_LEN;
   
    public ClientReceiver(Socket s)
    {
        this.socket=s;
       
    }
    public boolean receive(int tcpGuid,String downfilename,String savefilename,FileState filestate)
    {
     this.downfilename =downfilename;
        this.savefilename=savefilename;
        try{   

            //通过Socket连接文件服务器
            Socket socket=this.socket;
            //创建网络接受流接受服务器文件数据
            InputStream netIn=socket.getInputStream();
            InputStream in=new DataInputStream(new BufferedInputStream(netIn));
            //创建网络输出流并提供数据包装器
            OutputStream netOut=socket.getOutputStream();
            OutputStream out=new DataOutputStream(new BufferedOutputStream(netOut));
           
            String stemp="";
            boolean isErrot=false;
            int num=0;
            //创建文件读取缓冲区
            byte[] buf=new byte[MAX_LEN];
            int len=0;
           
            //=========(1)========下载命令,含tcpGuid
            stemp=CommonData.MYLINK_CMD_DOWND+tcpGuid+CommonData.MYLINK_ENDCHAR;
            len=stemp.getBytes().length;
            buf=new byte[len];
            buf=stemp.getBytes();
            out.write(buf,0,buf.length);
            out.flush();
            System.out.println("1.>>>>>>>>>>发出下载命令:"+stemp);

            //=========(2)========响应服务端请求,发送文件名
            buf=new byte[MAX_LEN];
   num=in.read(buf);
   stemp=new String(buf,0,num,"gb2312");
   System.out.println("2.<<<<<<<<<<收到文件名请求:"+stemp);
   
   if (stemp.startsWith(CommonData.MYLINK_REQ_FILENAME)){
             stemp=CommonData.MYLINK_FILENAME+downfilename+CommonData.MYLINK_ENDCHAR;
             len=stemp.getBytes().length;
             buf=new byte[len];
             buf=stemp.getBytes();
             out.write(buf,0,buf.length);
             out.flush();
             System.out.println("3.>>>>>>>>>>发出文件名:"+stemp);
            }else if (stemp.startsWith(CommonData.MYLINK_ERROR)){
            stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_ERROR);
           System.out.println("**********"+stemp+" 异常退出!");
           filestate.setMemo(stemp);
           isErrot=true;
           return false;
          }else{
           stemp="协议不对!";
           System.out.println("**********"+stemp);
           filestate.setMemo(stemp);
           //发送错误信号
                 stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                 len=stemp.getBytes().length;
                 buf=new byte[len];
                 buf=stemp.getBytes();
                 out.write(buf,0,buf.length);
                 out.flush();
                 isErrot=true;
           return false;
          }
           
   //=========(3)========获取回应消息,取得文件大小
   buf=new byte[MAX_LEN];
   num=in.read(buf);
   stemp=new String(buf,0,num,"gb2312");
   System.out.println("4.<<<<<<<<<<收到文件大小:"+stemp);
   if (stemp.startsWith(CommonData.MYLINK_LENGTH)){
    filesize=Long.parseLong(CommonFun.getTagString(stemp,CommonData.MYLINK_LENGTH));//求得文件大小
    if(filesize>0){
     isReady=true;
    }else{
     isReady=false;
    }
   }else if (stemp.startsWith(CommonData.MYLINK_ERROR)){
            stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_ERROR);
           System.out.println("**********"+stemp+" 异常退出!");
           filestate.setMemo(stemp);
          }else{
           stemp="协议不对!";
           System.out.println("**********"+stemp);
           filestate.setMemo(stemp);
           //发送错误信号
                 stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                 len=stemp.getBytes().length;
                 buf=new byte[len];
                 buf=stemp.getBytes();
                 out.write(buf,0,buf.length);
                 out.flush();
                 isErrot=true;
           return false;
          }

   if(isErrot){System.out.println("**********"+" 异常退出!");}
   else{
       File file=new File(savefilename);
             RandomAccessFile raf=null;
             //检查本地是否已存在该文件
             if (file.exists()){
                 //已存在,则取其长度,以便告诉服务端从哪个位置起传输
                 npost=file.length();
             }else{
                 //不存在,则创建本地空文件
              /**若路径不存在,则创建*/
           try{
            
            File filepath=new File(CommonFun.getFilePath(savefilename));
            if(!filepath.exists()){
             filepath.mkdirs();
            }
           }catch(Exception e){
            System.out.println("**********创建文件路径失败");
           }

                 file.createNewFile();
                 npost=0;
             }
             //刷新文件状态
    long totalnum=npost;
    int totalprog=(int)((totalnum/filesize)*100);
    filestate.setPosition(totalnum);
    
             //=========(4)========发送起始位置npost
             stemp=CommonData.MYLINK_POSITION+npost+CommonData.MYLINK_ENDCHAR;
             len=stemp.getBytes().length;
                buf=new byte[len];
             buf=stemp.getBytes();
             out.write(buf,0,buf.length);
             out.flush();
             System.out.println("5.>>>>>>>>>>发出断点续传定位:"+stemp);

    //写入文件前,先定位
             raf=new RandomAccessFile(file,"rw");
             raf.seek(npost);
            
             System.out.println("==========开始接收数据");
            
             //=========(5)========获取网络中的数据并写入文件  
    buf=new byte[MAX_LEN];
             num=in.read(buf);
             totalnum=totalnum+num;
             while(num!=(-1)){//是否读完所有数据

                    raf.write(buf,0,num);//将数据写往文件

                    raf.skipBytes(num);//顺序写文件字节

                    num=in.read(buf);//继续从网络中读取文件
                    //刷新文件状态
           if(num!=(-1)){
             totalnum=totalnum+num;
             totalprog=(int)(totalnum*100/filesize);
             filestate.setPosition(totalnum);
             filestate.setProgress(totalprog);
             //System.out.println(totalprog);
           }
             }
             System.out.println("==========下载完毕");  
             System.out.println("==========文件保存在:"+savefilename);  
             raf.close();
             filestate.setIsEnd(true);//传输完毕
   }
           
   if(in!=null)in=null;
            if(out!=null)out=null;
            return true;
        }catch(IOException e)
        {
            e.printStackTrace();
            return false;
        }finally{
         try{
          socket.close();
         }catch(IOException e)
         {
                e.printStackTrace();
            }
        }
    }
}

6、服务端发送文件:ServerSender.java


package com.myLink.tcp.server;
import java.io.*;
import java.net.*;
import com.myLink.common.*;
/**
 * 日期: 2007-3-28
 * 作者: 黄京亮
 * 描述: 服务端发送文件
 * 参数:
 * 原理:
 * 0、服务端:监听socket端口;
 * 1、客户端:发出DOWND命令;
 * 2、服务端:收到命令后向客户端请求文件名;
 * 3、客户端:收到请求,发出文件名;
 * 4、服务端:收到文件名后检查本地是否存在该文件,存在则发出文件大小
 * 5、客户端:收到文件大小后检查本地是否已存在,并发出文件已接收到的大小(断点续传);
 * 6、服务端:收到传输的起始位置后,先定位再发送,完毕。
 * 7、客户端:接收文件,完毕。
 */
public class ServerSender extends Thread
{
    private Socket socket;
    private String datapath="";
    private String filename="";
    private FileInputStream fos=null;
    private long npost=0; //定义为当前位置
    private Tcp tcp=null;
    private static final int MAX_LEN=CommonData.SEND_MAX_LEN;
   
 public ServerSender (Socket s,Tcp tcp)
 {
     this.socket=s;
     this.tcp=tcp;
     this.filename=tcp.getFilePath()+tcp.getFileName();
 }

 public void run ()
 {
     try
        {
      //创建网络服务器接受客户请求
            Socket socket=this.socket;
            //创建网络接受流接受服务器文件数据
            InputStream netIn=socket.getInputStream();
            InputStream in=new DataInputStream(new BufferedInputStream(netIn));
            //创建网络输出流并提供数据包装器
            OutputStream netOut=socket.getOutputStream();
            OutputStream out=new DataOutputStream(new BufferedOutputStream(netOut));
           
            String stemp="";
            boolean isError=false;
            int num=0;
            //创建文件读取缓冲区
            byte[] buf=new byte[MAX_LEN];
            int len=0;

            //if(filename==null||filename==""||filename.equals("")){

             //(1)首先请求文件名
             stemp=CommonData.MYLINK_REQ_FILENAME;
             len=stemp.getBytes().length;
             buf=new byte[len];
             buf=stemp.getBytes();
             out.write(buf,0,buf.length);
             out.flush();
             System.out.println("1.>>>>>>>>>>请求文件名:"+stemp);
 
             //(2)接收文件名
             buf=new byte[MAX_LEN];
    num=in.read(buf);
    stemp=new String(buf,0,num,"gb2312");
    if (stemp.startsWith(CommonData.MYLINK_FILENAME)){
                 stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_FILENAME);
                 this.filename =stemp;
                 tcp.setFileName(CommonFun.getFileName(filename));
                 tcp.setFilePath(CommonFun.getFilePath(filename));
                 System.out.println("2.<<<<<<<<<<收到文件名:"+stemp);
             }else if (stemp.startsWith(CommonData.MYLINK_ERROR)){
             stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_ERROR);
            System.out.println("**********"+stemp);
            isError=true;
           }else{
            stemp="协议不对!";
            System.out.println("**********"+stemp);

            //发送错误信号
                  stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                  len=stemp.getBytes().length;
                  buf=new byte[len];
                  buf=stemp.getBytes();
                  out.write(buf,0,buf.length);
                  out.flush();
                  isError=true;
           }
            //}


   if(isError){System.out.println("**********"+"异常退出");}
   else if (!filename.equals(null) && !filename.equals("")){
             File file=new File(filename);
            
             //检查文件是否存在
             if (file.exists()){
              fos=new FileInputStream(file);
                 tcp.setFileSize(file.length());
              //(3)文件存在,准备就绪,发送文件大小
                 stemp=CommonData.MYLINK_LENGTH+file.length()+CommonData.MYLINK_ENDCHAR;
                 len=stemp.getBytes().length;
                 buf=new byte[len];
                 buf=stemp.getBytes();
                 out.write(buf,0,buf.length);
                 out.flush();
                 System.out.println("3.>>>>>>>>>>发出文件大小:"+stemp);
 
                 //==========(4)=========获取起始位置npost,并定位
        buf=new byte[MAX_LEN];
        num=in.read(buf);
        stemp=new String(buf,0,num,"gb2312");
        if (stemp.startsWith(CommonData.MYLINK_POSITION)){
                     stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_POSITION);
                     npost=Integer.parseInt(stemp);
                     System.out.println("4.<<<<<<<<<<收到断点定位:"+stemp);
                 }else if (stemp.startsWith(CommonData.MYLINK_ERROR)){
              stemp=CommonFun.getTagString(stemp,CommonData.MYLINK_ERROR);
             System.out.println("**********"+stemp);
             isError=true;
            }else{
             stemp="协议不对!";
             System.out.println("**********"+stemp);

             //发送错误信号
                   stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                   len=stemp.getBytes().length;
                   buf=new byte[len];
                   buf=stemp.getBytes();
                   out.write(buf,0,buf.length);
                   out.flush();
                   isError=true;
            }
        
        
     if(isError){System.out.println("**********"+"异常退出");}
     else{
         //读文件前,先定位
         fos.skip(npost);
         
         System.out.println("=========开始发送数据");
      //==========(5)=========读出文件中的数据并发送
      buf=new byte[MAX_LEN];
         num=fos.read(buf);
     
         while(num!=(-1)){//是否读完文件
     
             out.write(buf,0,num);//把文件数据写出网络缓冲区
     
             out.flush();//刷新缓冲区把数据写往客户端
     
             num=fos.read(buf);//继续从文件中读取数据
     
         }
     }
              fos.close();
              tcp.setSuccess(true);//成功
              System.out.println("==========上传完毕");
             }else{
              //文件不存在,发送错误信号
              stemp="所请求文件不存在!";
              System.out.println("**********"+stemp);
                    stemp=CommonData.MYLINK_ERROR+stemp+CommonData.MYLINK_ENDCHAR;
                    len=stemp.getBytes().length;
                    buf=new byte[len];
                    buf=stemp.getBytes();
                    out.write(buf,0,buf.length);
                    out.flush();
             }
   }else{
       System.out.println("**********"+"客户端没有指定要下载的文件名");
   }
   
   if(in!=null)in=null;
            if(out!=null)out=null;
        }catch(IOException e)
        {
         try{
          fos.close();
         }catch(IOException e2)
         {
                //e2.printStackTrace();
          System.out.println("**********关闭文件出错/n"+e2.toString());
            }
            //e.printStackTrace();
         System.out.println("**********传输连接断开/n"+e.toString());
        }finally{
         try{
          tcp.setDoAlready(true);//已处理,里面调用了setChanged()
          tcp.notifyObservers(tcp);//====tcp.setDoAlready(true)里先调用setChanged();然后再通知
          socket.close();
         }catch(IOException e)
         {
                //e.printStackTrace();
                System.out.println("**********关闭socket出错/n"+e.toString());
            }
        }
 }
}

 

注:本文只是最主要的传输部分。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值