杰瑞科技汇

java socket上传文件

Java Socket 文件上传实现指南

下面我将提供一个完整的 Java Socket 文件上传实现方案,包括服务器端和客户端代码。

java socket上传文件-图1
(图片来源网络,侵删)

服务器端实现

import java.io.*;
import java.net.*;
public class FileUploadServer {
    public static void main(String[] args) {
        int port = 12345;
        try (ServerSocket serverSocket = new ServerSocket(port)) {
            System.out.println("服务器启动,等待客户端连接...");
            while (true) {
                try (Socket clientSocket = serverSocket.accept();
                     DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
                     FileOutputStream fos = new FileOutputStream("received_" + System.currentTimeMillis() + ".txt")) {
                    // 读取文件名
                    String fileName = dis.readUTF();
                    System.out.println("正在接收文件: " + fileName);
                    // 读取文件大小
                    long fileSize = dis.readLong();
                    System.out.println("文件大小: " + fileSize + " bytes");
                    // 读取文件内容
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    long totalBytesRead = 0;
                    while (totalBytesRead < fileSize && (bytesRead = dis.read(buffer)) != -1) {
                        fos.write(buffer, 0, bytesRead);
                        totalBytesRead += bytesRead;
                    }
                    System.out.println("文件接收完成: " + fileName);
                } catch (IOException e) {
                    System.err.println("处理客户端请求时出错: " + e.getMessage());
                }
            }
        } catch (IOException e) {
            System.err.println("服务器启动失败: " + e.getMessage());
        }
    }
}

客户端实现

import java.io.*;
import java.net.*;
public class FileUploadClient {
    public static void main(String[] args) {
        String serverAddress = "localhost";
        int port = 12345;
        String filePath = "example.txt"; // 要上传的文件路径
        try (Socket socket = new Socket(serverAddress, port);
             DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
             FileInputStream fis = new FileInputStream(filePath)) {
            // 发送文件名
            File file = new File(filePath);
            dos.writeUTF(file.getName());
            // 发送文件大小
            long fileSize = file.length();
            dos.writeLong(fileSize);
            // 发送文件内容
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                dos.write(buffer, 0, bytesRead);
            }
            System.out.println("文件上传完成: " + filePath);
        } catch (IOException e) {
            System.err.println("上传文件时出错: " + e.getMessage());
        }
    }
}

增强版实现(带进度显示和错误处理)

服务器端增强版

import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class EnhancedFileUploadServer {
    private static final int PORT = 12345;
    private static final int THREAD_POOL_SIZE = 10;
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("增强版文件上传服务器启动,监听端口: " + PORT);
            while (true) {
                Socket clientSocket = serverSocket.accept();
                threadPool.execute(new FileUploadHandler(clientSocket));
            }
        } catch (IOException e) {
            System.err.println("服务器启动失败: " + e.getMessage());
        } finally {
            threadPool.shutdown();
        }
    }
    private static class FileUploadHandler implements Runnable {
        private final Socket clientSocket;
        public FileUploadHandler(Socket socket) {
            this.clientSocket = socket;
        }
        @Override
        public void run() {
            String clientAddress = clientSocket.getInetAddress().getHostAddress();
            System.out.println("客户端连接: " + clientAddress);
            try (DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
                 FileOutputStream fos = new FileOutputStream("received_" + System.currentTimeMillis() + ".txt")) {
                // 读取文件名
                String fileName = dis.readUTF();
                System.out.println("正在接收文件: " + fileName + " 来自: " + clientAddress);
                // 读取文件大小
                long fileSize = dis.readLong();
                System.out.println("文件大小: " + fileSize + " bytes");
                // 读取文件内容并显示进度
                byte[] buffer = new byte[4096];
                int bytesRead;
                long totalBytesRead = 0;
                int progress = 0;
                while (totalBytesRead < fileSize && (bytesRead = dis.read(buffer)) != -1) {
                    fos.write(buffer, 0, bytesRead);
                    totalBytesRead += bytesRead;
                    // 计算并显示进度
                    int currentProgress = (int) ((totalBytesRead * 100) / fileSize);
                    if (currentProgress > progress) {
                        progress = currentProgress;
                        System.out.printf("接收进度: %d%%%n", progress);
                    }
                }
                System.out.println("文件接收完成: " + fileName + " 来自: " + clientAddress);
            } catch (IOException e) {
                System.err.println("处理客户端 " + clientAddress + " 时出错: " + e.getMessage());
            } finally {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                    System.err.println("关闭客户端连接时出错: " + e.getMessage());
                }
            }
        }
    }
}

客户端增强版

import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class EnhancedFileUploadClient {
    private static final String SERVER_ADDRESS = "localhost";
    private static final int PORT = 12345;
    public static void main(String[] args) {
        if (args.length != 1) {
            System.out.println("用法: java EnhancedFileUploadClient <文件路径>");
            return;
        }
        String filePath = args[0];
        File file = new File(filePath);
        if (!file.exists() || !file.isFile()) {
            System.err.println("文件不存在或不是有效文件: " + filePath);
            return;
        }
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<Integer> future = executor.submit(new FileUploadTask(file));
        try {
            int result = future.get();
            if (result == 0) {
                System.out.println("文件上传成功: " + filePath);
            } else {
                System.err.println("文件上传失败,错误码: " + result);
            }
        } catch (InterruptedException | ExecutionException e) {
            System.err.println("上传过程中出错: " + e.getMessage());
        } finally {
            executor.shutdown();
        }
    }
    private static class FileUploadTask implements Callable<Integer> {
        private final File file;
        public FileUploadTask(File file) {
            this.file = file;
        }
        @Override
        public Integer call() {
            try (Socket socket = new Socket(SERVER_ADDRESS, PORT);
                 DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                 FileInputStream fis = new FileInputStream(file)) {
                // 发送文件名
                dos.writeUTF(file.getName());
                // 发送文件大小
                long fileSize = file.length();
                dos.writeLong(fileSize);
                // 发送文件内容并显示进度
                byte[] buffer = new byte[4096];
                int bytesRead;
                long totalBytesWritten = 0;
                int progress = 0;
                while ((bytesRead = fis.read(buffer)) != -1) {
                    dos.write(buffer, 0, bytesRead);
                    totalBytesWritten += bytesRead;
                    // 计算并显示进度
                    int currentProgress = (int) ((totalBytesWritten * 100) / fileSize);
                    if (currentProgress > progress) {
                        progress = currentProgress;
                        System.out.printf("上传进度: %d%%%n", progress);
                    }
                }
                return 0; // 成功返回0
            } catch (UnknownHostException e) {
                System.err.println("无法连接到服务器: " + e.getMessage());
                return 1;
            } catch (IOException e) {
                System.err.println("上传文件时出错: " + e.getMessage());
                return 2;
            }
        }
    }
}

使用说明

  1. 启动服务器

    java EnhancedFileUploadServer
  2. 启动客户端(上传文件):

    java EnhancedFileUploadClient example.txt

关键点说明

  1. 数据流处理

    • 使用 DataInputStreamDataOutputStream 来处理文件名和文件大小等元数据
    • 使用 FileInputStreamFileOutputStream 处理文件内容
  2. 进度显示

    java socket上传文件-图2
    (图片来源网络,侵删)

    通过计算已传输字节数占总字节数的百分比来显示进度

  3. 多线程处理

    服务器使用线程池处理多个客户端并发上传

  4. 错误处理

    java socket上传文件-图3
    (图片来源网络,侵删)

    对文件不存在、网络错误等情况进行了处理

  5. 性能优化

    使用缓冲区(4096字节)减少I/O操作次数

扩展建议

  1. 可以添加文件校验(如MD5或SHA校验)确保文件完整性
  2. 可以实现断点续传功能
  3. 可以添加用户认证机制
  4. 可以支持大文件分块上传
  5. 可以添加SSL/TLS加密传输

这个实现提供了基本的文件上传功能,可以根据实际需求进行扩展和优化。

分享:
扫描分享到社交APP
上一篇
下一篇