由于需要研究了下用 java socket 传输文件,由于需要传输多个文件,因此,采用了多线程设计。客户端每个线程创建一个 socket 连接,每个 socket 连接负责传输一个文件,服务端的ServerSocket每次 accept 一个 socket 连接,创建一个线程用于接收客户端传来的文件。 1、服务端 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TransferServer { private int defaultBindPort = Constants.DEFAULT_BIND_PORT; //默认监听端口号为10000 private int tryBindTimes = 0; //初始的绑定端口的次数设定为0 private ServerSocket serverSocket; //服务套接字等待对方的连接和文件发送 private ExecutorService executorService; //线程池 private final int POOL_SIZE = 4; //单个CPU的线程池大小 /** * 不带参数的构造器,选用默认的端口号 * @throws Exception */ public TransferServer() throws Exception{ try { this.bingToServerPort(defaultBindPort); executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE); System.out.println("开辟线程数 : " + Runtime.getRuntime().availableProcessors() * POOL_SIZE); } catch (Exception e) { throw new Exception("绑定端口不成功!"); } } /** * 带参数的构造器,选用用户指定的端口号 * @param port * @throws Exception */ public TransferServer(int port) throws Exception{ try { this.bingToServerPort(port); executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE); } catch (Exception e) { throw new Exception("绑定端口不成功!"); } } private void bingToServerPort(int port) throws Exception{ try { serverSocket = new ServerSocket(port); System.out.println(port); System.out.println("服务启动!"); } catch (Exception e) { this.tryBindTimes = this.tryBindTimes + 1; port = port + this.tryBindTimes; if(this.tryBindTimes >= 20){ throw new Exception("您已经尝试很多次了,但是仍无法绑定到指定的端口!请重新选择绑定的默认端口号"); } //递归绑定端口 this.bingToServerPort(port); } } public void service(){ Socket socket = null; while (true) { try { socket = serverSocket.accept(); executorService.execute(new Handler(socket)); } catch (Exception e) { e.printStackTrace(); } } } class Handler implements Runnable{ private Socket socket; public Handler(Socket socket){ this.socket = socket; } public void run() { System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort()); DataInputStream dis = null; DataOutputStream dos = null; int bufferSize = 8192; byte[] buf = new byte[bufferSize]; try { dis = new DataInputStream(new BufferedInputStream(socket.getInputStream())); String savePath = Constants.RECEIVE_FILE_PATH + dis.readUTF(); long length = dis.readLong(); dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(savePath))); int read = 0; long passedlen = 0; while ((read = dis.read(buf)) != -1) { passedlen += read; dos.write(buf, 0, read); System.out.println("文件[" + savePath + "]已经接收: " + passedlen * 100L/ length + "%"); } System.out.println("文件: " + savePath + "接收完成!"); } catch (Exception e) { e.printStackTrace(); System.out.println("接收文件失败!"); }finally{ try { if(dos != null){ dos.close(); } if(dis != null){ dis.close(); } if(socket != null){ socket.close(); } } catch (Exception e) { e.printStackTrace(); } } } } public static void main(String[] args) throws Exception{ new TransferServer().service(); } } 2、客户端 import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.net.Socket; import java.util.ArrayList; import java.util.Random; import java.util.Vector; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TransferClient { private static ArrayList<String> fileList = new ArrayList<String>(); private String sendFilePath = Constants.SEND_FILE_PATH; /** * 带参数的构造器,用户设定需要传送文件的文件夹 * @param filePath */ public TransferClient(String filePath){ getFilePath(filePath); } /** * 不带参数的构造器。使用默认的传送文件的文件夹 */ public TransferClient(){ getFilePath(sendFilePath); } public void service(){ ExecutorService executorService = Executors.newCachedThreadPool(); Vector<Integer> vector = getRandom(fileList.size()); for(Integer integer : vector){ String filePath = fileList.get(integer.intValue()); executorService.execute(sendFile(filePath)); } } private void getFilePath(String dirPath){ File dir = new File(dirPath); File[] files = dir.listFiles(); if(files == null){ return; } for(int i = 0; i < files.length; i++){ if(files[i].isDirectory()){ getFilePath(files[i].getAbsolutePath()); } else { fileList.add(files[i].getAbsolutePath()); } } } private Vector<Integer> getRandom(int size){ Vector<Integer> v = new Vector<Integer>(); Random r = new Random(); boolean b = true; while(b){ int i = r.nextInt(size); if(!v.contains(i)) v.add(i); if(v.size() == size) b = false; } return v; } private static Runnable sendFile(final String filePath){ return new Runnable(){ private Socket socket = null; private String ip ="localhost"; private int port = 10000; public void run() { System.out.println("开始发送文件:" + filePath); File file = new File(filePath); if(createConnection()){ int bufferSize = 8192; byte[] buf = new byte[bufferSize]; try { DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath))); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeUTF(file.getName()); dos.flush(); dos.writeLong(file.length()); dos.flush(); int read = 0; int passedlen = 0; long length = file.length(); //获得要发送文件的长度 while ((read = fis.read(buf)) != -1) { passedlen += read; System.out.println("已经完成文件 [" + file.getName() + "]百分比: " + passedlen * 100L/ length + "%"); dos.write(buf, 0, read); } dos.flush(); fis.close(); dos.close(); socket.close(); System.out.println("文件 " + filePath + "传输完成!"); } catch (Exception e) { e.printStackTrace(); } } } private boolean createConnection() { try { socket = new Socket(ip, port); System.out.println("连接服务器成功!"); return true; } catch (Exception e) { System.out.println("连接服务器失败!"); return false; } } }; } public static void main(String[] args){ new TransferClient().service(); } } 3、常量类 public interface Constants { public final static String RECEIVE_FILE_PATH = "E:\\receive\\"; public final static String SEND_FILE_PATH = "E:\\send"; public final static int DEFAULT_BIND_PORT = 10000; }
相关推荐
总结来说,Java Socket多线程文件传输实例项目是一个综合性的实践,涵盖了网络编程、多线程并发控制以及文件I/O等多个核心Java技术。通过这个项目,开发者可以深入理解如何在实际场景中运用这些技术,解决并发文件...
Java Socket是Java网络编程的基础,它提供了在网络之间进行通信的能力。多线程是Java编程中的一个重要概念,允许程序同时执行多个...通过这个实例,我们可以深入理解Java Socket和多线程在实际网络应用程序中的应用。
总的来说,本项目结合了Java的Socket通信、多线程并发控制、Hibernate ORM以及MySQL数据库,构建了一个能处理并发网络请求并存储信息的系统。这样的设计使得系统具备良好的扩展性和健壮性,能够高效地服务大量用户。...
Java Socket 多线程实现文件传输是一个常见的网络编程...通过以上介绍,你应该对Java Socket多线程实现文件传输有了基本的理解。实际开发中,还需要根据具体需求进行调整和优化,例如添加进度显示、文件校验等功能。
在Java编程中,Socket通信是网络应用程序之间进行数据交换的基础,尤其在文件传输...总的来说,使用Java的Socket和多线程技术实现文件夹传输是一项复杂的任务,需要掌握网络编程、多线程、文件操作等多个方面的知识。
Java Socket多线程文件上传下载实例项目是一种基于Java网络编程技术实现的,旨在处理大量并发连接的文件传输服务。在本项目中,Socket是客户端与服务器之间通信的基础,它允许两个应用程序通过网络交换数据。多线程...
总的来说,这个Java Socket聊天和文件传输工具是一个很好的学习和实践案例,涵盖了网络编程、多线程、文件I/O等多个Java核心技术。无论是对初学者还是经验丰富的开发者来说,都能从中受益,提升自己的技能。通过深入...
以上就是使用Java Socket编程实现文件上传涉及到的主要知识点,包括Socket通信机制、文件I/O、数据库操作、异常处理、多线程、安全性和性能优化等方面。理解并掌握这些内容,对于开发高效、可靠的文件上传系统至关...
总的来说,"java,socket多线程一对一聊天"项目涵盖了Java网络编程的基础知识,包括Socket通信、多线程以及基本的消息传递机制。虽然不支持并发,但对于学习和理解这些基本概念仍然很有价值。在实际应用中,可以通过...
这个Java Socket工具的实现涉及到了网络编程、多线程、I/O流和文件操作等多个Java核心技术,对于学习和理解Java网络编程有很好的实践价值。如果你对这些技术感兴趣,可以通过编写自己的Socket程序进行实践,加深理解...
**打包生成的jar文件**(多线程传输.jar)是一个可执行的Java程序,包含了项目的所有类和资源,用户可以直接运行它,无需编译源代码。而FileTransfer.zip可能是项目源代码的压缩包,包含.java文件和其他必要的配置...
总的来说,Java Socket多线程通信是一种强大的工具,用于构建分布式系统和网络应用。理解如何创建和管理Socket连接,以及如何在多线程环境下处理这些连接,是成为熟练的Java网络程序员的关键步骤。通过实践和理解...
Java Socket多线程聊天程序是一种实现网络通信的基本方式,它基于TCP/IP协议,允许两台计算机之间进行双向数据传输。在这个简单的两人对话程序中,我们主要涉及到以下知识点: 1. **Socket**: Java中的Socket类是...
总的来说,"java多线程网络传输文件(非同步)"这个主题涉及到Java多线程、Socket编程以及文件I/O等核心知识。通过多线程实现并发处理客户端请求,利用Socket进行网络通信,以及处理文件的读写操作,这些是构建一个...
总结起来,Java Socket多线程通讯实例展示了如何利用Java的网络编程API实现TCP通信,并通过多线程处理并发连接,这在构建例如QQ这样的聊天应用时是非常重要的技术。通过这种方式,服务端能够有效地管理大量并发的...
综上所述,Java Socket结合多线程技术,使得我们可以构建能够高效处理多个客户端连接的服务端应用程序,实现自定义对象的网络传输,这对于开发分布式系统或网络应用具有重要意义。在实际项目中,还需要考虑安全性、...
在Java编程语言中,Socket是实现网络通信的基本组件。"Java Socket学习---单线程阻塞"这个主题主要探讨了如何使用Java的Socket类进行单线程的阻塞式通信,这种模式通常用于简单的客户端-服务器应用。在这个场景中,...