Java使用Socket通信传输文件的方法示例

 更新时间:2017年06月22日 09:55:52   作者:kongxx  
这篇文章主要介绍了Java使用Socket通信传输文件的方法,结合实例形式分析了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方法。

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类来向服务器发送文件以及接受服务器响应文件。运行完后,分别检查服务器和客户端接收到的文件。

更多关于java相关内容感兴趣的读者可查看本站专题:《Java Socket编程技巧总结》、《Java文件与目录操作技巧汇总》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

相关文章

  • java打jar包的几种方式详解

    java打jar包的几种方式详解

    这篇文章主要介绍了java打jar包的几种方式,本文分步骤给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-11-11
  • Java实现队列的N种方法

    Java实现队列的N种方法

    在Java中,我们可以使用不同的方式来实现队列,本文主要介绍了Java实现队列的N种方法,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • Spring中集成Groovy的四种方式(小结)

    Spring中集成Groovy的四种方式(小结)

    这篇文章主要介绍了Spring中集成Groovy的四种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 浅谈Maven安装及环境配置出错的解决办法

    浅谈Maven安装及环境配置出错的解决办法

    这篇文章主要介绍了浅谈Maven安装及环境配置出错的解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • MyBatis JdbcType 与Oracle、MySql数据类型对应关系说明

    MyBatis JdbcType 与Oracle、MySql数据类型对应关系说明

    这篇文章主要介绍了MyBatis JdbcType 与Oracle、MySql数据类型对应关系说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java API如何实现向Hive批量导入数据

    Java API如何实现向Hive批量导入数据

    这篇文章主要介绍了Java API如何实现向Hive批量导入数据的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 深入理解Spring事务的传播行为

    深入理解Spring事务的传播行为

    Spring在TransactionDefinition接口中规定了7种类型的事务传播行为。下面这篇文章主要给大家介绍了关于Spring事务传播行为的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-02-02
  • MyBatis-Plus拦截器实现数据权限控制的方法

    MyBatis-Plus拦截器实现数据权限控制的方法

    MyBatis-Plus是一款基于MyBatis的增强工具,它提供了一些便捷的功能和增强的查询能力,数据权限控制是在系统中对用户访问数据进行限制的一种机制,这篇文章主要给大家介绍了关于MyBatis-Plus拦截器实现数据权限控制的相关资料,需要的朋友可以参考下
    2024-01-01
  • java判断中文字符串长度的简单实例

    java判断中文字符串长度的简单实例

    下面小编就为大家带来一篇java判断中文字符串长度的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 关于Spring框架中异常处理情况浅析

    关于Spring框架中异常处理情况浅析

    最近学习Spring时,认识到Spring异常处理的强大,这篇文章主要给大家介绍了关于Spring框架中异常处理情况的相关资料,通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-08-08

最新评论