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
相关产品推荐
相关产品推荐

