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());
}
}
}
}
注:本文只是最主要的传输部分。