Java Socket实战之七 使用Socket通信传输文件

               

本文地址:http://blog.csdn.net/kongxx/article/details/7319410

Java Socket实战之一 单线程通信

Java Socket实战之二 多线程通信

Java Socket实战之三 传输对象

Java Socket实战之四 传输压缩对象

Java Socket实战之五 使用加密协议传输对象

Java Socket实战之六 使用NIO包实现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方法。

package com.googlecode.garbagecan.test.socket.nio;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.ClosedChannelException;import java.nio.channels.FileChannel;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.logging.Level;import java.util.logging.Logger;public class MyServer4 private final static Logger logger = Logger.getLogger(MyServer4.class.getName());  public static void main(String[] args) {  Selector selector = null;  ServerSocketChannel serverSocketChannel = null;    try {   // Selector for incoming time requests   selector = Selector.open();   // Create a new server socket and set to non blocking mode   serverSocketChannel = ServerSocketChannel.open();   serverSocketChannel.configureBlocking(false);      // Bind the server socket to the local host and port   serverSocketChannel.socket().setReuseAddress(true);   serverSocketChannel.socket().bind(new InetSocketAddress(10000));      // Register accepts on the server socket with the selector. This   // step tells the selector that the socket wants to be put on the   // ready list when accept operations occur, so allowing multiplexed   // non-blocking I/O to take place.   serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);    // Here's where everything happens. The select method will   // return when any operations registered above have occurred, the   // thread has been interrupted, etc.   while (selector.select() > 0) {    // Someone is ready for I/O, get the ready keys    Iterator<SelectionKey> it = selector.selectedKeys().iterator();     // Walk through the ready keys collection and process date requests.    while (it.hasNext()) {     SelectionKey readyKey = it.next();     it.remove();          // The key indexes into the selector so you     // can retrieve the socket that's ready for I/O     doit((ServerSocketChannel) readyKey.channel());    }   }  } catch (ClosedChannelException ex) {   logger.log(Level.SEVERE, null, ex);  } catch (IOException ex) {   logger.log(Level.SEVERE, null, ex);  } finally {   try {    selector.close();   } catch(Exception ex) {}   try {    serverSocketChannel.close();   } catch(Exception ex) {}  } } private static void doit(final ServerSocketChannel serverSocketChannel) throws IOException {  SocketChannel socketChannel = null;  try {   socketChannel = serverSocketChannel.accept();      receiveFile(socketChannel, new File("E:/test/server_receive.log"));   sendFile(socketChannel, new File("E:/test/server_send.log"));  } finally {   try {    socketChannel.close();   } catch(Exception ex) {}  }   }  private static void receiveFile(SocketChannel socketChannel, File file) throws IOException {  FileOutputStream fos = null;  FileChannel channel = null;    try {   fos = new FileOutputStream(file);   channel = fos.getChannel();   ByteBuffer buffer = ByteBuffer.allocateDirect(1024);   int size = 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(Exception ex) {}   try {    fos.close();   } catch(Exception ex) {}  } } private static void sendFile(SocketChannel socketChannel, File file) throws IOException {  FileInputStream fis = null;  FileChannel channel = null;  try {   fis = new FileInputStream(file);   channel = fis.getChannel();   ByteBuffer buffer = ByteBuffer.allocateDirect(1024);   int size = 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(Exception ex) {}   try {    fis.close();   } catch(Exception ex) {}  } }}
下面是Client程序代码,也主要关注sendFile和receiveFile方法

package com.googlecode.garbagecan.test.socket.nio;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.net.InetSocketAddress;import java.net.SocketAddress;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.SocketChannel;import java.util.logging.Level;import java.util.logging.Logger;public class MyClient4 private final static Logger logger = Logger.getLogger(MyClient4.class.getName());  public static void main(String[] args) throws Exception {  new Thread(new MyRunnable()).start(); }  private static final class MyRunnable implements Runnable {  public void run() {   SocketChannel socketChannel = null;   try {    socketChannel = SocketChannel.open();    SocketAddress socketAddress = new InetSocketAddress("localhost", 10000);    socketChannel.connect(socketAddress);    sendFile(socketChannel, new File("E:/test/client_send.log"));    receiveFile(socketChannel, new File("E:/test/client_receive.log"));   } catch (Exception ex) {    logger.log(Level.SEVERE, null, ex);   } finally {    try {     socketChannel.close();    } catch(Exception ex) {}   }  }  private void sendFile(SocketChannel socketChannel, File file) throws IOException {   FileInputStream fis = null;   FileChannel channel = null;   try {    fis = new FileInputStream(file);    channel = fis.getChannel();    ByteBuffer buffer = ByteBuffer.allocateDirect(1024);    int size = 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(Exception ex) {}    try {     fis.close();    } catch(Exception ex) {}   }  }  private void receiveFile(SocketChannel socketChannel, File file) throws IOException {   FileOutputStream fos = null;   FileChannel channel = null;      try {    fos = new FileOutputStream(file);    channel = fos.getChannel();    ByteBuffer buffer = ByteBuffer.allocateDirect(1024);    int size = 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(Exception ex) {}    try {     fos.close();    } catch(Exception ex) {}   }  } }}
首先运行MyServer4类启动监听,然后运行MyClient4类来向服务器发送文件以及接受服务器响应文件。运行完后,分别检查服务器和客户端接收到的文件。






           
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值