java文件传输.docx
- 文档编号:6997958
- 上传时间:2023-01-15
- 格式:DOCX
- 页数:19
- 大小:98.96KB
java文件传输.docx
《java文件传输.docx》由会员分享,可在线阅读,更多相关《java文件传输.docx(19页珍藏版)》请在冰豆网上搜索。
java文件传输
生产者-消费者同步问题
班级:
信安091姓名:
苏海学号:
0907300426日期:
2011/11/15
1.实验目的
通过本实验,了解网络的基本通信原理和编程方法,初步掌握网络的传输层上的编程,了解什么是非阻塞文件传输,学会使用SocketChannel、ServerSocketChannel编写简单的网络通信软件。
2.实验环境
已安装win7操作系统的微机一台、eclipse。
3.实验内容
1.实现一个采用用户自定义协议的文件传输服务器FileServer和客户FileClient。
当FileClient发送请求“GETxxx.xxx”时,FileServer就把xxx.xxx文件发送给FileClient,FileClient把该文件保存到客户端的本地文件系统中,当FileClient发送请求“PUTxxx.xxx”时,FileServer就做好接收xxx.xxx文件的准备,FileClient接着发送xxx.xxx文件的内容,FileServer把接收到的文件内容保存到服务器的本地文件系统。
GET或PUT命令中的文件允许采用相对路径,其根路径由用户自定义的FILE_PATH系统属性指定。
4.具体设计要求及有关说明
(1)建立文件传输服务器FileServer和客户FileClient。
(2)共创建EchoServer类、EchoClient类
(3)使用SocketChannel、ServerSocketChannel完成上述问题。
(4)主要利用java.nio包的ServerSocketChannel类和SocketChannel类来实现服务器和客户端的链接以及数据的发送和接收,利用Selector类和SelectionKey类来实现非阻塞的功能,java.nio.Buffer类则是用来作为缓冲区存放中间数据,FileChannel类是用来实现文件的读写功能,使用多线程使FileClient能够连续输入用户命令而不用等待FileServer的响应结果。
5.源代码
//EchoServer类
importjava.nio.*;
importjava.io.*;
importjava.nio.channels.*;
importjava.nio.charset.*;
import.*;
importjava.util.*;
publicclassEchoServer{
privateSelectorselector=null;
privateServerSocketChannelserverSocketChannel=null;
privateintport=8000;
privateCharsetcharset=Charset.forName("GBK");
privateStringFILE_PATH="D:
\\down";
publicEchoServer()throwsIOException
{
selector=Selector.open();
serverSocketChannel=ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(newInetSocketAddress(port));
System.out.println("服务器启动");
}
publicvoidservice()throwsIOException
{
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
while(selector.select()>0)
{
SetreadyKeys=selector.selectedKeys();
Iteratorit=readyKeys.iterator();
while(it.hasNext())
{
SelectionKeykey=null;
try
{
key=(SelectionKey)it.next();
it.remove();
if(key.isAcceptable())
{
ServerSocketChannelssc=(ServerSocketChannel)key.channel();
SocketChannelsocketChannel=(SocketChannel)ssc.accept();
System.out.println("接收到客户连接,来自"+socketChannel.socket().getInetAddress()+"端口:
"+socketChannel.socket().getPort());
socketChannel.configureBlocking(false);
ByteBufferbuffer=ByteBuffer.allocate(1024);
socketChannel.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE,buffer);
}
if(key.isReadable())
{
receive(key);
}
}
catch(IOExceptione)
{
e.printStackTrace();
}
}
}
}
publicvoidreceive(SelectionKeykey)throwsIOException
{
SocketChannelsocketChannel=(SocketChannel)key.channel();
ByteBufferreadBuf=ByteBuffer.allocate(3);
socketChannel.read(readBuf);//把通道的数据读到readBuf中
readBuf.flip();
Strings=decode(readBuf);
if(s.equals("GET"))//如果是GET则准备发送文件
{
try{
intbytePath=getFileLength(socketChannel);
Stringpath=getPath(socketChannel,bytePath);//获得文件路径
FileInputStreamfis=newFileInputStream(path);//文件输入流
Stringerro="yes";
ByteBufferbuffer=ByteBuffer.allocate(3);
buffer.put(encode(erro));
buffer.flip();
while(buffer.hasRemaining())
socketChannel.write(buffer);
intbytes=fis.available();//获得文件总字节数
socketChannel.write(encode(String.valueOf(bytes)+"/r/n"));//发送文件大小
System.out.println("文件大小:
"+bytes+"字节");
intfilebytes=path.substring(8).getBytes("GBK").length;
socketChannel.write(encode(String.valueOf(filebytes)+"/r/n"));//发送文件名字的字节数
socketChannel.write(encode(path.substring(8)));//发送文件名
FileChannelfic=fis.getChannel();//文件输入流通道
fic.position(0);
buffer=ByteBuffer.allocate(1024*1024);
intbyteRead=0;
doublebyteWrite=0;
System.out.println("正在发送文件!
");
intb=0;
while(byteRead>=0)
{
byteRead=fic.read(buffer);
if(byteRead==-1)
break;
buffer.flip();
byteWrite+=byteRead;
while(b>0)
{
System.out.print('\b');
b--;
}
System.out.print("已发送完成"+(int)(byteWrite*100/bytes)+"%");
b=("已发送完成"+String.valueOf((int)(byteWrite*100/bytes))+"%").getBytes().length;
while(buffer.hasRemaining())
socketChannel.write(buffer);
pact();
}
System.out.println();
System.out.println(path+"文件发送完成!
");
}catch(FileNotFoundExceptione)
{
Stringerro="err";
ByteBufferbuffer=ByteBuffer.allocate(3);
buffer.put(encode(erro));
buffer.flip();
while(buffer.hasRemaining())
socketChannel.write(buffer);
}
}
else
if(s.equals("PUT"))
{
intbytePath=getFileLength(socketChannel);
Stringpath=getPath(socketChannel,bytePath);//获得文件存放的路径
intbytes=getFileLength(socketChannel);//要接受的文件总字节数
System.out.println("文件大小:
"+bytes+"字节");
FileOutputStreamfos=newFileOutputStream(path);
FileChannelfoc=fos.getChannel();
foc.position(0);
ByteBufferbuffer=ByteBuffer.allocate(1024*1024);
System.out.println("正在接收文件。
。
。
");
doublebyteRead=0;
intbyteAll=bytes;
intb=0;
while(bytes>0)
{
if(bytes<1024*1024)
{
buffer=ByteBuffer.allocate(bytes);
}
socketChannel.read(buffer);
intposition=buffer.position();//记录当前读到的文件长度
buffer.flip();
while(buffer.hasRemaining())
foc.write(buffer);
pact();
bytes=bytes-position;
byteRead+=position;
while(b>0)
{
System.out.print('\b');
b--;
}
System.out.print("已完成"+(int)(byteRead*100/byteAll)+"%.");
b=("已完成"+String.valueOf((int)(byteRead*100/byteAll))+"%.").getBytes().length;
}
System.out.println();
System.out.println(path+"文件接收完成!
");
}
elseif(s.equals("bye"))
{
socketChannel.close();
key.cancel();
System.out.println("退出程序。
");
System.exit(0);
}
}
//解码
publicStringdecode(ByteBufferbuffer)
{
CharBuffercharBuffer=charset.decode(buffer);
returncharBuffer.toString();
}
//编码
publicByteBufferencode(Stringstr)
{
returncharset.encode(str);
}
//获得文件存放路径
publicStringgetPath(SocketChannelsocketChannel,intfileNameLength)throwsIOException
{
ByteBufferreadBuf=ByteBuffer.allocate(fileNameLength);
socketChannel.read(readBuf);
readBuf.flip();
Stringpath=FILE_PATH+"\\"+decode(readBuf);
returnpath;
}
//获得文件长度
publicintgetFileLength(SocketChannelsocketChannel)throwsIOException
{
ByteBufferreadBuf=ByteBuffer.allocate
(1);
Stringacount="";
while(!
acount.endsWith("/r/n"))
{
socketChannel.read(readBuf);
readBuf.flip();
acount+=decode(readBuf);
readBpact();
}
acount=acount.substring(1,acount.indexOf("/r/n"));
returnInteger.parseInt(acount);
}
/**
*@paramargs
*/
publicstaticvoidmain(String[]args){
//TODO自动生成方法存根
try
{
newEchoServer().service();
}
catch(IOExceptione)
{
e.printStackTrace();
}
}
}
//EchoClient类
import.*;
importjava.nio.*;
importjava.io.*;
importjava.nio.channels.*;
importjava.nio.charset.*;
importjava.util.*;
publicclassEchoClient{
privateSocketChannelsocketChannel=null;
privateSelectorselector;
privateStringFILE_PATH="E:
\\down\\";
privateCharsetcharset=Charset.forName("GBK");
privateByteBuffersendCMDBuffer=ByteBuffer.allocate(1024);//存发送命令
publicEchoClient()throwsIOException
{
socketChannel=SocketChannel.open();
selector=Selector.open();
InetAddressis=InetAddress.getLocalHost();
InetSocketAddressisa=newInetSocketAddress(is,8000);
socketChannel.connect(isa);
socketChannel.configureBlocking(false);
System.out.println("与服务器连接成功!
");
}
publicvoidreceiveFromUser()//接受用户输入
{
try
{
BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));
Stringmsg=null;
while((msg=br.readLine())!
=null)
{
if(msg.length()<3)
{
System.out.println("输入命令有错!
!
!
");
}
if(msg.equals("bye"))
{
synchronized(sendCMDBuffer)
{
sendCMDBuffer.put(encode(msg+"/r/n"));
}
break;
}
else
if(msg.substring(0,3).equals("PUT")||msg.substring(0,3).equals("GET"))
synchronized(sendCMDBuffer)
{
sendCMDBuffer.put(encode(msg+"/r/n"));
}
else
System.out.println("输入命令有错!
!
!
");
}
}
catch(IOExceptione)
{
e.printStackTrace();
}
}
publicvoidservice()throwsIOException
{
socketChannel.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE);//注册事件
while(selector.select()>0)
{
SetreadyKeys=selector.selectedKeys();
Iteratorit=readyKeys.iterator();
while(it.hasNext())
{
SelectionKeykey=null;
try
{
key=(SelectionKey)it.next();
it.remove();
if(key.isReadable())
{
receive(key);
}
if(key.isWritable())
{
send(key);
}
Thread.sleep(100);
}
catch(InterruptedExceptione)
{
e.printStackTrace();
}
catch(FileNotFoundExceptione)
{
System.out.println("文件不存在!
");
continue;
}
catch(IOExceptione)
{
e.printStackTrace();
try
{
if(key!
=null)
key.cancel();
key.channel().close();
}catch(Exceptionee)
{
ee.printStackTrace();
}
}
}
}
}
publicvoidsend(SelectionKeykey)throwsIOException
{
StringsubCMD;
synchronized(sendCMDBuffer)
{
sendCMDBuffer.flip();
StringCMD=decode(sendCMDBuffer);
if(CMD.indexOf("/r/n")==-1)//还没有完整的命令输入
{
sendCMDBuffer.limit(sendCMDBuffer.capacity());//把极限设置为容量
return;
}
subCMD=CMD.substring(0,CMD.indexOf("/r/n"));
sendCMDBpact();
sendCMDBuffer.put(encode(CMD.substring(CMD.indexOf("/r/n")+4)));
}
if(subCMD.substring(0,3).equals("PUT"))//如果是SET命令
{
Stringpath=subCMD.s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 文件传输