Java使用Socket通信传输文件的方法示例
本文实例讲述了Java使用Socket通信传输文件的方法。分享给大家供大家参考,具体如下:
前面几篇文章介绍了使用Java的Socket编程和NIO包在Socket中的应用,这篇文章说说怎样利用Socket编程来实现简单的文件传输。
这里由于前面一片文章介绍了NIO在Socket中的应用,所以这里在读写文件的时候也继续使用NIO包,所以代码看起来会比直接使用流的方式稍微复杂一点点。
下面的示例演示了客户端向服务器端发送一个文件,服务器作为响应给客户端回发一个文件。这里准备两个文件E:/test/server_send.log和E:/test/client.send.log文件,在测试完毕后在客户端和服务器相同目录下会多出两个文件E:/test/server_receive.log和E:/test/client.receive.log文件。
下面首先来看看Server类,主要关注其中的sendFile和receiveFile方法。
packagecom.googlecode.garbagecan.test.socket.nio; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileOutputStream; importjava.io.IOException; importjava.net.InetSocketAddress; importjava.nio.ByteBuffer; importjava.nio.channels.ClosedChannelException; importjava.nio.channels.FileChannel; importjava.nio.channels.SelectionKey; importjava.nio.channels.Selector; importjava.nio.channels.ServerSocketChannel; importjava.nio.channels.SocketChannel; importjava.util.Iterator; importjava.util.logging.Level; importjava.util.logging.Logger; publicclassMyServer4{ privatefinalstaticLoggerlogger=Logger.getLogger(MyServer4.class.getName()); publicstaticvoidmain(String[]args){ Selectorselector=null; ServerSocketChannelserverSocketChannel=null; try{ //Selectorforincomingtimerequests selector=Selector.open(); //Createanewserversocketandsettononblockingmode serverSocketChannel=ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); //Bindtheserversockettothelocalhostandport serverSocketChannel.socket().setReuseAddress(true); serverSocketChannel.socket().bind(newInetSocketAddress(10000)); //Registeracceptsontheserversocketwiththeselector.This //steptellstheselectorthatthesocketwantstobeputonthe //readylistwhenacceptoperationsoccur,soallowingmultiplexed //non-blockingI/Ototakeplace. serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT); //Here'swhereeverythinghappens.Theselectmethodwill //returnwhenanyoperationsregisteredabovehaveoccurred,the //threadhasbeeninterrupted,etc. while(selector.select()>0){ //SomeoneisreadyforI/O,getthereadykeys Iteratorit=selector.selectedKeys().iterator(); //Walkthroughthereadykeyscollectionandprocessdaterequests. while(it.hasNext()){ SelectionKeyreadyKey=it.next(); it.remove(); //Thekeyindexesintotheselectorsoyou //canretrievethesocketthat'sreadyforI/O doit((ServerSocketChannel)readyKey.channel()); } } }catch(ClosedChannelExceptionex){ logger.log(Level.SEVERE,null,ex); }catch(IOExceptionex){ logger.log(Level.SEVERE,null,ex); }finally{ try{ selector.close(); }catch(Exceptionex){} try{ serverSocketChannel.close(); }catch(Exceptionex){} } } privatestaticvoiddoit(finalServerSocketChannelserverSocketChannel)throwsIOException{ SocketChannelsocketChannel=null; try{ socketChannel=serverSocketChannel.accept(); receiveFile(socketChannel,newFile("E:/test/server_receive.log")); sendFile(socketChannel,newFile("E:/test/server_send.log")); }finally{ try{ socketChannel.close(); }catch(Exceptionex){} } } privatestaticvoidreceiveFile(SocketChannelsocketChannel,Filefile)throwsIOException{ FileOutputStreamfos=null; FileChannelchannel=null; try{ fos=newFileOutputStream(file); channel=fos.getChannel(); ByteBufferbuffer=ByteBuffer.allocateDirect(1024); intsize=0; while((size=socketChannel.read(buffer))!=-1){ buffer.flip(); if(size>0){ buffer.limit(size); channel.write(buffer); buffer.clear(); } } }finally{ try{ channel.close(); }catch(Exceptionex){} try{ fos.close(); }catch(Exceptionex){} } } privatestaticvoidsendFile(SocketChannelsocketChannel,Filefile)throwsIOException{ FileInputStreamfis=null; FileChannelchannel=null; try{ fis=newFileInputStream(file); channel=fis.getChannel(); ByteBufferbuffer=ByteBuffer.allocateDirect(1024); intsize=0; while((size=channel.read(buffer))!=-1){ buffer.rewind(); buffer.limit(size); socketChannel.write(buffer); buffer.clear(); } socketChannel.socket().shutdownOutput(); }finally{ try{ channel.close(); }catch(Exceptionex){} try{ fis.close(); }catch(Exceptionex){} } } }
下面是Client程序代码,也主要关注sendFile和receiveFile方法
packagecom.googlecode.garbagecan.test.socket.nio; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileOutputStream; importjava.io.IOException; importjava.net.InetSocketAddress; importjava.net.SocketAddress; importjava.nio.ByteBuffer; importjava.nio.channels.FileChannel; importjava.nio.channels.SocketChannel; importjava.util.logging.Level; importjava.util.logging.Logger; publicclassMyClient4{ privatefinalstaticLoggerlogger=Logger.getLogger(MyClient4.class.getName()); publicstaticvoidmain(String[]args)throwsException{ newThread(newMyRunnable()).start(); } privatestaticfinalclassMyRunnableimplementsRunnable{ publicvoidrun(){ SocketChannelsocketChannel=null; try{ socketChannel=SocketChannel.open(); SocketAddresssocketAddress=newInetSocketAddress("localhost",10000); socketChannel.connect(socketAddress); sendFile(socketChannel,newFile("E:/test/client_send.log")); receiveFile(socketChannel,newFile("E:/test/client_receive.log")); }catch(Exceptionex){ logger.log(Level.SEVERE,null,ex); }finally{ try{ socketChannel.close(); }catch(Exceptionex){} } } privatevoidsendFile(SocketChannelsocketChannel,Filefile)throwsIOException{ FileInputStreamfis=null; FileChannelchannel=null; try{ fis=newFileInputStream(file); channel=fis.getChannel(); ByteBufferbuffer=ByteBuffer.allocateDirect(1024); intsize=0; while((size=channel.read(buffer))!=-1){ buffer.rewind(); buffer.limit(size); socketChannel.write(buffer); buffer.clear(); } socketChannel.socket().shutdownOutput(); }finally{ try{ channel.close(); }catch(Exceptionex){} try{ fis.close(); }catch(Exceptionex){} } } privatevoidreceiveFile(SocketChannelsocketChannel,Filefile)throwsIOException{ FileOutputStreamfos=null; FileChannelchannel=null; try{ fos=newFileOutputStream(file); channel=fos.getChannel(); ByteBufferbuffer=ByteBuffer.allocateDirect(1024); intsize=0; while((size=socketChannel.read(buffer))!=-1){ buffer.flip(); if(size>0){ buffer.limit(size); channel.write(buffer); buffer.clear(); } } }finally{ try{ channel.close(); }catch(Exceptionex){} try{ fos.close(); }catch(Exceptionex){} } } } }
首先运行MyServer4类启动监听,然后运行MyClient4类来向服务器发送文件以及接受服务器响应文件。运行完后,分别检查服务器和客户端接收到的文件。
更多关于java相关内容感兴趣的读者可查看本站专题:《JavaSocket编程技巧总结》、《Java文件与目录操作技巧汇总》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。