[转载]Java Socket实战之七 使用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方法。

  1. package com.googlecode.garbagecan.test.socket.nio;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.net.InetSocketAddress;  
  8. import java.nio.ByteBuffer;  
  9. import java.nio.channels.ClosedChannelException;  
  10. import java.nio.channels.FileChannel;  
  11. import java.nio.channels.SelectionKey;  
  12. import java.nio.channels.Selector;  
  13. import java.nio.channels.ServerSocketChannel;  
  14. import java.nio.channels.SocketChannel;  
  15. import java.util.Iterator;  
  16. import java.util.logging.Level;  
  17. import java.util.logging.Logger;  
  18.   
  19. public class MyServer4 {  
  20.   
  21.     private final static Logger logger = Logger.getLogger(MyServer4.class.getName());  
  22.       
  23.     public static void main(String[] args) {  
  24.         Selector selector = null;  
  25.         ServerSocketChannel serverSocketChannel = null;  
  26.           
  27.         try {  
  28.             // Selector for incoming time requests  
  29.             selector = Selector.open();  
  30.   
  31.             // Create a new server socket and set to non blocking mode  
  32.             serverSocketChannel = ServerSocketChannel.open();  
  33.             serverSocketChannel.configureBlocking(false);  
  34.               
  35.             // Bind the server socket to the local host and port  
  36.             serverSocketChannel.socket().setReuseAddress(true);  
  37.             serverSocketChannel.socket().bind(new InetSocketAddress(10000));  
  38.               
  39.             // Register accepts on the server socket with the selector. This  
  40.             // step tells the selector that the socket wants to be put on the  
  41.             // ready list when accept operations occur, so allowing multiplexed  
  42.             // non-blocking I/O to take place.  
  43.             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);  
  44.       
  45.             // Here's where everything happens. The select method will  
  46.             // return when any operations registered above have occurred, the  
  47.             // thread has been interrupted, etc.  
  48.             while (selector.select() > 0) {  
  49.                 // Someone is ready for I/O, get the ready keys  
  50.                 Iterator<SelectionKey> it = selector.selectedKeys().iterator();  
  51.       
  52.                 // Walk through the ready keys collection and process date requests.  
  53.                 while (it.hasNext()) {  
  54.                     SelectionKey readyKey = it.next();  
  55.                     it.remove();  
  56.                       
  57.                     // The key indexes into the selector so you  
  58.                     // can retrieve the socket that's ready for I/O  
  59.                     doit((ServerSocketChannel) readyKey.channel());  
  60.                 }  
  61.             }  
  62.         } catch (ClosedChannelException ex) {  
  63.             logger.log(Level.SEVERE, null, ex);  
  64.         } catch (IOException ex) {  
  65.             logger.log(Level.SEVERE, null, ex);  
  66.         } finally {  
  67.             try {  
  68.                 selector.close();  
  69.             } catch(Exception ex) {}  
  70.             try {  
  71.                 serverSocketChannel.close();  
  72.             } catch(Exception ex) {}  
  73.         }  
  74.     }  
  75.   
  76.     private static void doit(final ServerSocketChannel serverSocketChannel) throws IOException {  
  77.         SocketChannel socketChannel = null;  
  78.         try {  
  79.             socketChannel = serverSocketChannel.accept();  
  80.               
  81.             receiveFile(socketChannel, new File("E:/test/server_receive.log"));  
  82.             sendFile(socketChannel, new File("E:/test/server_send.log"));  
  83.         } finally {  
  84.             try {  
  85.                 socketChannel.close();  
  86.             } catch(Exception ex) {}  
  87.         }  
  88.           
  89.     }  
  90.       
  91.     private static void receiveFile(SocketChannel socketChannel, File file) throws IOException {  
  92.         FileOutputStream fos = null;  
  93.         FileChannel channel = null;  
  94.           
  95.         try {  
  96.             fos = new FileOutputStream(file);  
  97.             channel = fos.getChannel();  
  98.             ByteBuffer buffer = ByteBuffer.allocateDirect(1024);  
  99.   
  100.             int size = 0;  
  101.             while ((size = socketChannel.read(buffer)) != -1) {  
  102.                 buffer.flip();  
  103.                 if (size > 0) {  
  104.                     buffer.limit(size);  
  105.                     channel.write(buffer);  
  106.                     buffer.clear();  
  107.                 }  
  108.             }  
  109.         } finally {  
  110.             try {  
  111.                 channel.close();  
  112.             } catch(Exception ex) {}  
  113.             try {  
  114.                 fos.close();  
  115.             } catch(Exception ex) {}  
  116.         }  
  117.     }  
  118.   
  119.     private static void sendFile(SocketChannel socketChannel, File file) throws IOException {  
  120.         FileInputStream fis = null;  
  121.         FileChannel channel = null;  
  122.         try {  
  123.             fis = new FileInputStream(file);  
  124.             channel = fis.getChannel();  
  125.             ByteBuffer buffer = ByteBuffer.allocateDirect(1024);  
  126.             int size = 0;  
  127.             while ((size = channel.read(buffer)) != -1) {  
  128.                 buffer.rewind();  
  129.                 buffer.limit(size);  
  130.                 socketChannel.write(buffer);  
  131.                 buffer.clear();  
  132.             }  
  133.             socketChannel.socket().shutdownOutput();  
  134.         } finally {  
  135.             try {  
  136.                 channel.close();  
  137.             } catch(Exception ex) {}  
  138.             try {  
  139.                 fis.close();  
  140.             } catch(Exception ex) {}  
  141.         }  
  142.     }  
  143. }  

下面是Client程序代码,也主要关注sendFile和receiveFile方法

  1. package com.googlecode.garbagecan.test.socket.nio;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7. import java.net.InetSocketAddress;  
  8. import java.net.SocketAddress;  
  9. import java.nio.ByteBuffer;  
  10. import java.nio.channels.FileChannel;  
  11. import java.nio.channels.SocketChannel;  
  12. import java.util.logging.Level;  
  13. import java.util.logging.Logger;  
  14.   
  15. public class MyClient4 {  
  16.   
  17.     private final static Logger logger = Logger.getLogger(MyClient4.class.getName());  
  18.       
  19.     public static void main(String[] args) throws Exception {  
  20.         new Thread(new MyRunnable()).start();  
  21.     }  
  22.       
  23.     private static final class MyRunnable implements Runnable {  
  24.         public void run() {  
  25.             SocketChannel socketChannel = null;  
  26.             try {  
  27.                 socketChannel = SocketChannel.open();  
  28.                 SocketAddress socketAddress = new InetSocketAddress("localhost", 10000);  
  29.                 socketChannel.connect(socketAddress);  
  30.   
  31.                 sendFile(socketChannel, new File("E:/test/client_send.log"));  
  32.                 receiveFile(socketChannel, new File("E:/test/client_receive.log"));  
  33.             } catch (Exception ex) {  
  34.                 logger.log(Level.SEVERE, null, ex);  
  35.             } finally {  
  36.                 try {  
  37.                     socketChannel.close();  
  38.                 } catch(Exception ex) {}  
  39.             }  
  40.         }  
  41.   
  42.         private void sendFile(SocketChannel socketChannel, File file) throws IOException {  
  43.             FileInputStream fis = null;  
  44.             FileChannel channel = null;  
  45.             try {  
  46.                 fis = new FileInputStream(file);  
  47.                 channel = fis.getChannel();  
  48.                 ByteBuffer buffer = ByteBuffer.allocateDirect(1024);  
  49.                 int size = 0;  
  50.                 while ((size = channel.read(buffer)) != -1) {  
  51.                     buffer.rewind();  
  52.                     buffer.limit(size);  
  53.                     socketChannel.write(buffer);  
  54.                     buffer.clear();  
  55.                 }  
  56.                 socketChannel.socket().shutdownOutput();  
  57.             } finally {  
  58.                 try {  
  59.                     channel.close();  
  60.                 } catch(Exception ex) {}  
  61.                 try {  
  62.                     fis.close();  
  63.                 } catch(Exception ex) {}  
  64.             }  
  65.         }  
  66.   
  67.         private void receiveFile(SocketChannel socketChannel, File file) throws IOException {  
  68.             FileOutputStream fos = null;  
  69.             FileChannel channel = null;  
  70.               
  71.             try {  
  72.                 fos = new FileOutputStream(file);  
  73.                 channel = fos.getChannel();  
  74.                 ByteBuffer buffer = ByteBuffer.allocateDirect(1024);  
  75.   
  76.                 int size = 0;  
  77.                 while ((size = socketChannel.read(buffer)) != -1) {  
  78.                     buffer.flip();  
  79.                     if (size > 0) {  
  80.                         buffer.limit(size);  
  81.                         channel.write(buffer);  
  82.                         buffer.clear();  
  83.                     }  
  84.                 }  
  85.             } finally {  
  86.                 try {  
  87.                     channel.close();  
  88.                 } catch(Exception ex) {}  
  89.                 try {  
  90.                     fos.close();  
  91.                 } catch(Exception ex) {}  
  92.             }  
  93.         }  
  94.     }  
  95. }  

首先运行MyServer4类启动监听,然后运行MyClient4类来向服务器发送文件以及接受服务器响应文件。运行完后,分别检查服务器和客户端接收到的文件。

posted @ 2015-01-03 00:25  chenlinyunyi  阅读(99)  评论(0编辑  收藏  举报