You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java文件服务器客户端二次操作报SocketException,求排查解决

问题分析与解决方案

核心问题1:服务器单次请求后关闭连接

服务器代码中,Socket、DataInputStream、DataOutputStream被包裹在try-with-resources块中,每次处理完一个请求后,这些资源会被自动关闭,而客户端是复用同一个Socket发送多次请求,导致第二次请求时连接已断开,抛出SocketException。

解决方法:将连接的处理逻辑改为长连接,即在一个Socket连接中处理多个请求,直到客户端发送exit指令或主动断开连接。修改服务器的主循环,在接受Socket后,内部再套一个循环处理该连接的所有请求。

核心问题2:全局path变量被修改导致路径错误

服务器使用static String path作为基础路径,每次处理请求时直接修改这个全局变量,后续请求的路径会出现拼接错误(比如replace操作可能无法正确恢复基础路径)。

解决方法:使用局部变量存储拼接后的文件路径,不要修改全局的基础路径。

核心问题3:字符串分割语法错误

代码中存在message.split(";"[1])的错误写法,正确的应该是message.split(";")[1],这种语法错误会导致运行时异常。


修改后的Server代码

package FileServer;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;

public class Server {

    private static final String BASE_PATH = "D:\\JavaFiles\\data\\";
    private static boolean isRunning = true;
    private static final int PORT = 34522;
    private static final HashMap<String, String> filenames = new HashMap<>();

    public static void main(String[] args) throws IOException {
        createDirectory(BASE_PATH);

        try (ServerSocket server = new ServerSocket(PORT)) {
            System.out.println("Server started");

            while (isRunning) {
                try (Socket socket = server.accept();
                     DataInputStream input = new DataInputStream(socket.getInputStream());
                     DataOutputStream output = new DataOutputStream(socket.getOutputStream())) {

                    boolean isClientConnected = true;
                    while (isClientConnected && isRunning) {
                        String message = input.readUTF();
                        String response = "";

                        if (message.equals("exit")) {
                            isClientConnected = false;
                            isRunning = false;
                            response = "exit";
                        } else {
                            String[] parts = message.split(";");
                            switch (parts[0]) {
                                case "PUT":
                                    if (parts.length > 1) {
                                        String filePath = BASE_PATH + parts[1];
                                        File f = new File(filePath);
                                        if (f.exists() && !f.isDirectory()) {
                                            response = "403";
                                        } else {
                                            int length = input.readInt();
                                            byte[] data = new byte[length];
                                            input.readFully(data);

                                            String hash = generateId(filePath);
                                            filenames.put(hash, filePath);

                                            try (FileOutputStream fos = new FileOutputStream(filePath)) {
                                                fos.write(data);
                                            } catch (IOException e) {
                                                e.printStackTrace();
                                                response = "500";
                                            }
                                            response = "200 " + hash;
                                        }
                                    } else {
                                        response = "400";
                                    }
                                    break;

                                case "GET":
                                    if (parts.length >=3) {
                                        String filePath = "";
                                        if (parts[1].equals("n")) {
                                            filePath = BASE_PATH + parts[2];
                                        } else {
                                            String id = parts[2];
                                            filePath = filenames.getOrDefault(id, "");
                                        }

                                        File f = new File(filePath);
                                        if (f.exists() && !f.isDirectory()) {
                                            response = "200";
                                            byte[] data = Files.readAllBytes(Paths.get(filePath));
                                            output.writeUTF(response);
                                            output.writeInt(data.length);
                                            output.write(data);
                                            output.flush();
                                            continue;
                                        } else {
                                            response = "403";
                                        }
                                    } else {
                                        response = "400";
                                    }
                                    break;

                                case "DELETE":
                                    if (parts.length >=3) {
                                        String filePath = "";
                                        if (parts[1].equals("n")) {
                                            filePath = BASE_PATH + parts[2];
                                        } else {
                                            String id = parts[2];
                                            filePath = filenames.getOrDefault(id, "");
                                        }

                                        File f = new File(filePath);
                                        if (f.exists() && !f.isDirectory()) {
                                            delete(filePath);
                                            filenames.values().remove(filePath);
                                            response = "200";
                                        } else {
                                            response = "403";
                                        }
                                    } else {
                                        response = "400";
                                    }
                                    break;

                                default:
                                    response = "400";
                            }
                        }
                        output.writeUTF(response);
                        output.flush();
                    }
                } catch (IOException e) {
                    System.out.println("Client disconnected: " + e.getMessage());
                }
            }
        }
    }

    public static void createDirectory(String path) {
        File fileDirectory = new File(path);
        if (!fileDirectory.exists()) {
            fileDirectory.mkdirs();
        }
    }

    public static String generateId(String filename) {
        return String.valueOf(Math.abs(filename.hashCode()));
    }

    public static void delete(String filepath) {
        File file = new File(filepath);
        if (file.exists() && !file.isDirectory()) {
            file.delete();
        }
    }
}

修改后的Client代码

package FileServer;

import java.io.*;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;

public class Client {

    private static boolean isRunning = true;
    public static Scanner scan = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        String address = "127.0.0.1";
        int port = 34522;

        try (Socket socket = new
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:08:26