您的位置:首页 > 其它

6.服务器与客户端双线程传输文件--客户端

2014-07-24 09:29 351 查看
/*
* 本程序主要功能:
* 客户端,双线程传输文件
* 其中一个线程向服务器端发送文件,一个线程从服务器端下载文件
*
*/

import java.io.*;//这里使用BufferedInputStream,BufferedReader,DataInputStream,File,
//IOException,InputStream,InputStreamReader,PrintWriter,
//RandomAccessFile 类
import java.net.*;//这里使用Socket,UnknownHostException 类

public class TestFileClient_1
{
public static String IP = "localhost";//Server的IP地址:localhost
public static int DEFAULT_PORT = 8000;//Server的端口号:8000
public Socket client = null;//新建一个Socket成员属性:client
public GetFile gf;//新建一个GetFile成员属性:gf
public SendFile sf;//新建一个SendFile成员属性:sf

public void start()//方法:启动服务
{
try
{
System.out.println("try to connect to Server...");//提示信息:尝试连接服务器
client = new Socket(IP,DEFAULT_PORT);//通过IP和端口号连接服务器,返回Socket对象,赋值给client
if(client != null)//client不为null时,成功连接服务器
{
System.out.println("Connect successfully!");//提示信息:成功连接服务器

sf = new SendFile(client);//通过client,创建一个SendFile对象:sf
gf = new GetFile(client);//通过client,创建一个GetFile对象:gf

sf.start();//启动sf对应的SendFile线程
gf.start();//启动gf对应的GetFile线程

}

}
catch(Exception e)
{
e.printStackTrace();
}
}

public static void main(String[] args)
{
// TODO 自动生成的方法存根
TestFileClient_1 tfc = new TestFileClient_1();//创建一个TestFileClient_1对象:tfc
tfc.start();//tfc启动服务
}

}

class SendFile extends Thread
{

public Socket client;//新建一个Socket成员属性:client
public FileInputStream fileInput;//新建一个InputStream成员属性:fileInput
public DataOutputStream fileOutput;//新建一个OutputStream成员属性:fileOutput
byte[] buf;//新建一个字节数组成员属性:buf

public SendFile(Socket client)
{
this.client = client;//将形参client赋值给属性client

try
{
buf = new byte[1024];//创建byte数组大小为1024个字节
fileOutput = new DataOutputStream(//创建一个数据输出流
new BufferedOutputStream(//创建一个缓冲输出流
this.client.getOutputStream()));//获取client的输出流
fileInput = new FileInputStream(new File("isClient.pdf"));//创建一个文件输入流,获取文件isClient.pdf的内容

}
catch(Exception e)
{
e.printStackTrace();
}
}

@Override//重写标记
public void run()//实现run方法
{
try
{
/*开始发送文件*/
int num = fileInput.read(buf);//从此输入流中将最多 buf.length个字节的数据读入一个 buf数组中。返回:读入缓冲区的字节总数
while(num != -1)//如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
{
fileOutput.write(buf, 0, num);//将buf数组中从0 开始的num个字节写入此文件输出流。
num = fileInput.read(buf);//从此输入流中将最多 buf.length个字节的数据读入一个 buf数组中。返回:读入缓冲区的字节总数
fileOutput.flush();//刷新输入缓冲区,并强制将输入缓冲区所有字节写出至目的地址
}

/*关闭流处理*/
fileInput.close();//关闭fileInput流
client.shutdownOutput();//禁用client的输出流。
//注意:这里不能使用OutputStream.close()方法。
//因为OutputStream.close()方法会将Socket关闭,使得GetFile线程造成异常
//也不能不进行关闭,因为不关闭会造成阻塞,无法正常使用GetFile的run()方法
}
catch(Exception e)
{
e.printStackTrace();
try
{
if(fileInput != null)
{
fileInput.close();//异常时,如果已经打开了fileInput,则关闭
}
if(fileOutput != null)
{
fileOutput.close();//异常时,如果已经打开了fileOutput,则关闭
}
}
catch(Exception e1)
{
e1.printStackTrace();
}
}
}
}

class GetFile extends Thread
{
public Socket client;//新建一个Socket成员属性:client
public DataInputStream fileInput;//新建一个DataInputStream成员属性:fileInput
public File file;//新建一个File成员属性:file
public RandomAccessFile rf;//新建一个RandomAccessFile成员属性:rf
public byte[] buf;

public GetFile(Socket client)
{
this.client = client;//将形参client赋值给属性client

try
{
buf = new byte[1024];//创建byte数组buf大小为1024个字节
file = new File("fromServer.pdf");//通过文件名"fromServer.pdf",创建一个File对象:file
file.createNewFile();//当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
rf = new RandomAccessFile(file,"rw");//通过file,创建从中读取和向其中写入的随机访问文件流对象:rf。
//"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
fileInput = new DataInputStream(//创建一个数据输入流
new BufferedInputStream(//创建一个缓冲输入流
this.client.getInputStream()));//获取client的输入流
}
catch(Exception e)
{
e.printStackTrace();
}

}

@Override//重写标记
public void run()//实现run方法
{
try
{
System.out.println("Downloading File...");//提示信息:下载文件中...

/*开始下载文件*/
int num = fileInput.read(buf);//从此输入流中将最多 buf.length个字节的数据读入一个 buf数组中。返回:读入缓冲区的字节总数
while(num != -1)//如果因为已经到达文件末尾而没有更多的数据,则返回 -1
{
rf.write(buf, 0, num);//将buf数组中从0 开始的num个字节写入此文件输出流
rf.skipBytes(num);//跳过num个字节数
num = fileInput.read(buf);//从此输入流中将最多 buf.length个字节的数据读入一个 buf数组中。返回:读入缓冲区的字节总数
}

/*关闭流处理*/
rf.close();//关闭RandomAccessFile流
client.shutdownInput();//禁用client的输入流。
//注意:这里不能使用InputStream.close()方法。
//因为InputStream.close()方法会将Socket关闭,使得SendFile线程造成异常
//也不能不进行关闭,因为不关闭会造成阻塞,无法正常使用SendFile的run()方法

System.out.println("Downloading Completely");//提示信息:下载完成

}
catch(Exception e)
{
e.printStackTrace();

try
{
if(fileInput != null)
{
fileInput.close();//异常时,如果已经打开了fileInput,则关闭
}
}
catch(Exception e1)
{
e1.printStackTrace();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐