Java Socket实现文件传输示例代码

最近学Socket学上瘾了,就写了一个简单的文件传输程序。

客户端设计思路:客户端与服务端建立连接,选择客户端本地文件,先将文件名及大小等属性发送给服务端,再将文件通过流的方式传输给服务端。传输的进度打印到控制台中,直到传输完成。

服务端设计思路:服务端接收客户端的请求(阻塞式),每接收到一个客户端请求连接后,就新开一个处理文件的线程,开始写入流,将文件到服务器的指定目录下,并与传输过来的文件同名。
下面是客户端和服务端的代码实现:

客户端代码:

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket; 

/**
 * 文件传输Client端<br>
 * 功能说明:
 *
 * @author 大智若愚的小懂
 * @Date 2016年09月01日
 * @version 1.0
 */
public class FileTransferClient extends Socket { 

  private static final String SERVER_IP = "127.0.0.1"; // 服务端IP
  private static final int SERVER_PORT = 8899; // 服务端端口 

  private Socket client; 

  private FileInputStream fis; 

  private DataOutputStream dos; 

  /**
   * 构造函数<br/>
   * 与服务器建立连接
   * @throws Exception
   */
  public FileTransferClient() throws Exception {
    super(SERVER_IP, SERVER_PORT);
    this.client = this;
    System.out.println("Cliect[port:" + client.getLocalPort() + "] 成功连接服务端");
  } 

  /**
   * 向服务端传输文件
   * @throws Exception
   */
  public void sendFile() throws Exception {
    try {
      File file = new File("E:\\JDK1.6中文参考手册(JDK_API_1_6_zh_CN).CHM");
      if(file.exists()) {
        fis = new FileInputStream(file);
        dos = new DataOutputStream(client.getOutputStream()); 

        // 文件名和长度
        dos.writeUTF(file.getName());
        dos.flush();
        dos.writeLong(file.length());
        dos.flush(); 

        // 开始传输文件
        System.out.println("======== 开始传输文件 ========");
        byte[] bytes = new byte[1024];
        int length = 0;
        long progress = 0;
        while((length = fis.read(bytes, 0, bytes.length)) != -1) {
          dos.write(bytes, 0, length);
          dos.flush();
          progress += length;
          System.out.print("| " + (100*progress/file.length()) + "% |");
        }
        System.out.println();
        System.out.println("======== 文件传输成功 ========");
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if(fis != null)
        fis.close();
      if(dos != null)
        dos.close();
      client.close();
    }
  } 

  /**
   * 入口
   * @param args
   */
  public static void main(String[] args) {
    try {
      FileTransferClient client = new FileTransferClient(); // 启动客户端连接
      client.sendFile(); // 传输文件
    } catch (Exception e) {
      e.printStackTrace();
    }
  } 

}

服务端代码:

import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.math.RoundingMode;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DecimalFormat; 

/**
 * 文件传输Server端<br>
 * 功能说明:
 *
 * @author 大智若愚的小懂
 * @Date 2016年09月01日
 * @version 1.0
 */
public class FileTransferServer extends ServerSocket { 

  private static final int SERVER_PORT = 8899; // 服务端端口 

  private static DecimalFormat df = null; 

  static {
    // 设置数字格式,保留一位有效小数
    df = new DecimalFormat("#0.0");
    df.setRoundingMode(RoundingMode.HALF_UP);
    df.setMinimumFractionDigits(1);
    df.setMaximumFractionDigits(1);
  } 

  public FileTransferServer() throws Exception {
    super(SERVER_PORT);
  } 

  /**
   * 使用线程处理每个客户端传输的文件
   * @throws Exception
   */
  public void load() throws Exception {
    while (true) {
      // server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的
      Socket socket = this.accept();
      /**
       * 我们的服务端处理客户端的连接请求是同步进行的, 每次接收到来自客户端的连接请求后,
       * 都要先跟当前的客户端通信完之后才能再处理下一个连接请求。 这在并发比较多的情况下会严重影响程序的性能,
       * 为此,我们可以把它改为如下这种异步处理与客户端通信的方式
       */
      // 每接收到一个Socket就建立一个新的线程来处理它
      new Thread(new Task(socket)).start();
    }
  } 

  /**
   * 处理客户端传输过来的文件线程类
   */
  class Task implements Runnable { 

    private Socket socket; 

    private DataInputStream dis; 

    private FileOutputStream fos; 

    public Task(Socket socket) {
      this.socket = socket;
    } 

    @Override
    public void run() {
      try {
        dis = new DataInputStream(socket.getInputStream()); 

        // 文件名和长度
        String fileName = dis.readUTF();
        long fileLength = dis.readLong();
        File directory = new File("D:\\FTCache");
        if(!directory.exists()) {
          directory.mkdir();
        }
        File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);
        fos = new FileOutputStream(file); 

        // 开始接收文件
        byte[] bytes = new byte[1024];
        int length = 0;
        while((length = dis.read(bytes, 0, bytes.length)) != -1) {
          fos.write(bytes, 0, length);
          fos.flush();
        }
        System.out.println("======== 文件接收成功 [File Name:" + fileName + "] [Size:" + getFormatFileSize(fileLength) + "] ========");
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        try {
          if(fos != null)
            fos.close();
          if(dis != null)
            dis.close();
          socket.close();
        } catch (Exception e) {}
      }
    }
  } 

  /**
   * 格式化文件大小
   * @param length
   * @return
   */
  private String getFormatFileSize(long length) {
    double size = ((double) length) / (1 << 30);
    if(size >= 1) {
      return df.format(size) + "GB";
    }
    size = ((double) length) / (1 << 20);
    if(size >= 1) {
      return df.format(size) + "MB";
    }
    size = ((double) length) / (1 << 10);
    if(size >= 1) {
      return df.format(size) + "KB";
    }
    return length + "B";
  } 

  /**
   * 入口
   * @param args
   */
  public static void main(String[] args) {
    try {
      FileTransferServer server = new FileTransferServer(); // 启动服务端
      server.load();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

测试的结果(客户端):

测试的结果(服务端):

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java基于Socket的文件传输实现方法

    本文实例讲述了Java基于Socket的文件传输实现方法.分享给大家供大家参考,具体如下: 1. Java代码如下: package sterning; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.net.Ser

  • 浅析Java基于Socket的文件传输案例

    本文实例介绍了Java基于Socket的文件传输案例,分享给大家供大家参考,具体内容如下 1.Java代码 package com.wf.demo.socket.socketfile; import java.net.*; import java.io.*; /** * 2.socket的Util辅助类 * * @author willson * */ public class ClientSocket { private String ip; private int port; private

  • Java IO流 文件传输基础

    一.文件的编码 package com.study.io; /** * 测试文件编码 */ public class EncodeDemo { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { String s="好好学习ABC"; byte[] bytes1=s.getBytes();//这是把字符串转换成字符数组,转换成的字节序列用的是

  • Java基于TCP方式的二进制文件传输

    一个基于Java Socket协议之上文件传输的完整示例,基于TCP通信完成. 除了基于TCP的二进制文件传输,还演示了JAVA Swing的一些编程技巧,Demo程序 实现主要功能有以下几点: 1.基于Java Socket的二进制文件传输(包括图片,二进制文件,各种文档work,PDF) 2.SwingWorker集合JProgressBar显示实时传输/接受完成的百分比 3.其它一些Swing多线程编程技巧 首先来看一下整个Dome的Class之间的关系图: 下面按照上图来详细解释各个类的

  • 基于socket和javaFX简单文件传输工具

    本文实例介绍了基于socket和javaFX简单文件传输工具,分享给大家供大家参考,具体内容如下 package application; import java.io.File; import org.james.component.ButtonBox; import org.james.component.FileReceiverGrid; import org.james.component.FileSenderGrid; import javafx.application.Applica

  • java 实现局域网文件传输的实例

    java 实现局域网文件传输的实例 本文主要实现局域网文件传输的实例,对java 的TCP知识,文件读写,Socket等知识的理解应用,很好的实例,大家参考下, 实现代码: ClientFile.java /** * 更多资料欢迎浏览凯哥学堂官网:http://kaige123.com * @author 小沫 */ package com.tcp.file; import java.io.File; import java.io.FileInputStream; import java.io.

  • Java Socket实现文件传输示例代码

    最近学Socket学上瘾了,就写了一个简单的文件传输程序. 客户端设计思路:客户端与服务端建立连接,选择客户端本地文件,先将文件名及大小等属性发送给服务端,再将文件通过流的方式传输给服务端.传输的进度打印到控制台中,直到传输完成. 服务端设计思路:服务端接收客户端的请求(阻塞式),每接收到一个客户端请求连接后,就新开一个处理文件的线程,开始写入流,将文件到服务器的指定目录下,并与传输过来的文件同名. 下面是客户端和服务端的代码实现: 客户端代码: import java.io.DataOutpu

  • java读取csv文件内容示例代码

    复制代码 代码如下: package com.huateng.readcsv; import java.io.BufferedReader;import java.io.FileReader;import java.util.ArrayList;import java.util.Iterator;import java.util.List; public class CsvUtil {        private String fileName = null;        private B

  • Java Socket实现的传输对象功能示例

    本文实例讲述了Java Socket实现的传输对象功能.分享给大家供大家参考,具体如下: 前面两篇文章介绍了怎样建立Java Socket通信,这里说一下怎样使用Java Socket来传输对象. 首先需要一个普通的对象类,由于需要序列化这个对象以便在网络上传输,所以实现java.io.Serializable接口就是必不可少的了,如下: package com.googlecode.garbagecan.test.socket.sample3; public class User implem

  • Java使用sftp定时下载文件的示例代码

    sftp简介 sftp是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的网络的加密方法.sftp 与 ftp 有着几乎一样的语法和功能.SFTP 为 SSH的其中一部分,是一种传输档案至 Blogger 伺服器的安全方式.其实在SSH软件包中,已经包含了一个叫作SFTP(Secure File Transfer Protocol)的安全文件信息传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)

  • java导出json格式文件的示例代码

    本文介绍了java导出json格式文件的示例代码,分享给大家,具体如下: 生成json文件代码: import java.io.File; import java.io.FileWriter; import java.io.Writer; public class CreateFileUtil { /** * 生成.json格式文件 */ public static boolean createJsonFile(String jsonString, String filePath, String

  • java压缩文件与删除文件的示例代码

    压缩文件 :toZip(String srcDir, OutputStream out,boolean KeepDirStructure) 删除文件:deleteFolder(File folder) /** * 压缩成ZIP 方法1 * * @param srcDir * 压缩文件夹路径 * @param out * 压缩文件输出流 * @param KeepDirStructure * 是否保留原来的目录结构,true:保留目录结构; * false:所有文件跑到压缩包根目录下(注意:不保留

  • Java实现图片转换PDF文件的示例代码

    最近因为一些事情,需要将一张简单的图片转换为PDF的文件格式,在网上找了一些工具,但是这些工具不是需要注册账号,就是需要下载软件. 而对于只是转换一张图片的情况下,这些操作显然是非常繁琐的,所以作者就直接使用Java写了一个图片转换PDF的系统,现在将该系统分享在这里. 引入依赖 <!--该项目以SpringBoot为基础搭建--> <parent> <groupId>org.springframework.boot</groupId> <artifa

  • Java定时调用.ktr文件的示例代码(解决方案)

    1.Maven依赖 <!-- Kettle --> <dependency> <groupId>pentaho-kettle</groupId> <artifactId>kettle-core</artifactId> <version>7.1.0.0-12</version> </dependency> <dependency> <groupId>pentaho-kettl

随机推荐