Socket closed报错。

问题遇到的现象和发生背景

上传完文件,关闭了data和file的io流,结果自动关闭了Socket,找不到合理的解决办法。

问题相关代码,请勿粘贴截图

服务器端

private synchronized void uploadFile() {
        try{
            String []arr = messageFromClient.split("\\s+");//分割多个空格
            String ID = arr[1];
            String creator = arr[2];
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            String description = arr[3];
            String filename = arr[4];
            byte[]buffer = new byte[1024];
            int length = 0;
            DataInputStream dis = new DataInputStream(connection.getInputStream());
            File file = new File(DataProcessing.uploadpath+filename);
            FileOutputStream fos = new FileOutputStream(file);
            while((length=dis.read(buffer))>0){
                fos.write(buffer, 0, length);
                fos.flush();
            }
            DataProcessing.insertDoc(ID,creator,timestamp,description,filename);
            dis.close();
            fos.close();
        }catch(IOException | SQLException e){
            e.printStackTrace();
        }
    }


GUI界面函数

private void uploadFile(AbstractUser user) {
        if(user.getRole().equals("browser")) {
            MainGUI.showError_Message(docPanel,"浏览人员无法录入档案!","提示信息");
        }
        else if(checkInput()){
            try {
                int choice = MainGUI.showConfirmMessage(jFrame, "确定要上传该档案吗?", "确认对话框");
                if (choice == JOptionPane.OK_OPTION) {
                    String ID = numberText.getText();
                    String Allfilename = fieldnameText.getText();
                    String description = text_Area.getText();
                    File tempFile = new File(Allfilename.trim());
                    String filename = tempFile.getName();
                    String creator = loginUser.getName();
                    Client.SendMessage("上传文件 " + ID + " " + creator +  " " + description + " " + filename);
                    Client.SendFile(tempFile);
                    if (Client.ReceiveMessage()) {
                        JOptionPane.showMessageDialog(jFrame, "上传文件成功!");
                    }
                    else
                        JOptionPane.showMessageDialog(jFrame, "上传文件失败!");
                    numberText.setText("");
                    fieldnameText.setText("");
                    text_Area.setText("");
                }
            }catch (IOException | ClassNotFoundException e) {
                JOptionPane.showMessageDialog(null, e.getLocalizedMessage());
            }
        }
    }


客户端函数

public static void SendFile(File tempFile){
        try {
            FileInputStream fis = new FileInputStream(tempFile);
            DataOutputStream dos = new DataOutputStream(client.getOutputStream());
            int length = 0;
            byte[]buffer = new byte[1024];
            while((length=fis.read(buffer))>0){
                dos.write(buffer, 0 , length);
                dos.flush();
            }
            fis.close();
            dos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

运行结果及报错内容

img

img

我的解答思路和尝试过的方法

我试过不进行io关闭但是还是会报错,可能是函数调用结束后会自动关闭函数里定义的io流(推测)。

我想要达到的结果

在上传后,不会关闭Socket。想知道造成这种情况的原因。



socket相关代码呢

package CS;


import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

    // 用户Socket对象
    private static Socket client;
    // 网络字符输入输出流IO
    private static ObjectInputStream input;
    private static ObjectOutputStream output;
    // 从服务端接收的信息
    private static String messageFromServer;

    // 连接服务器
    public static void ConnectToServer() throws UnknownHostException, IOException {
        System.out.println("\n正在尝试连接服务器...\n");
        // Socket构造函数参数为IP地址与端口号
        client = new Socket("127.0.0.1", 8000);
        System.out.println("已连接至:" + client.getInetAddress().getHostName());
    }

    // 构造IO流
    public static void GetStreams() throws IOException {
        output = new ObjectOutputStream(client.getOutputStream());
        output.flush();
        input = new ObjectInputStream(client.getInputStream());
        System.out.println("IO构造完成\n");
    }

    // 断开连接
    public static void CloseConnection() throws IOException {
        output.close();
        input.close();
        client.close();
    }

    // 用户向服务器发送消息
    public static void SendMessage(String message) throws IOException {
        // 写入输出流
        output.writeObject(message);
        output.flush();
    }

    // 接收服务器回传的消息
    public static boolean ReceiveMessage() throws ClassNotFoundException, IOException {
        // 读入输入流
        messageFromServer = (String) input.readObject();

        if(messageFromServer.equals("新增用户")
                ||messageFromServer.equals("修改用户")
                ||messageFromServer.equals("删除用户")
                ||messageFromServer.equals("上传文件")
                ||messageFromServer.equals("下载文件")
                ||messageFromServer.equals("修改密码")
                ||messageFromServer.equals("登录")){
            System.out.println("SERVER>>> " + messageFromServer);
            return true;
        }
        else {
            System.out.println("SERVER>>> " + messageFromServer);
            return false;
        }
    }
    public static void SendFile(File tempFile){
        try {
            FileInputStream fis = new FileInputStream(tempFile);
            DataOutputStream dos = new DataOutputStream(client.getOutputStream());
            int length = 0;
            byte[]buffer = new byte[1024];
            while((length=fis.read(buffer))>0){
                dos.write(buffer, 0 , length);
                dos.flush();
            }
            fis.close();
            dos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void ReceiveFile(File tempFile){
        try {
            DataInputStream dis = new DataInputStream(client.getInputStream());
            FileOutputStream fos = new FileOutputStream(tempFile);
            int length = 0;
            byte[]buffer = new byte[1024];
            while((length=dis.read(buffer))>0){
                fos.write(buffer, 0 , length);
                fos.flush();
            }
            dis.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}



```java
package CS;

import consoel.AbstractUser;
import consoel.DataProcessing;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;

public class Server extends Thread{
    private static ArrayList<ObjectOutputStream> outputToClients;
    // 网络字节输入流
    private ObjectInputStream input;

    // 服务器的ServerSocket对象
    private static ServerSocket server;
    // 接收连接用户的Socket对象connection
    private Socket connection;

    // 线程编号
    private static int counter = 0;
    // 线程名称
    private String name;
    // 接收用户的信息
    private String messageFromClient;

    // 构造方法
    public Server(Socket connection, String name) {
        this.connection = connection;
        this.name = name;
        try {
            // 构建input流
            input = new ObjectInputStream(connection.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 运行态方法
    public void run() {
        try {

            // 构建output流
            ObjectOutputStream output = new ObjectOutputStream(connection.getOutputStream());
            outputToClients.add(output);
            System.out.println("IO构造完成\n");
            String []arr;
            do {
                // 读取用户信息
                messageFromClient = (String) input.readObject();
                arr = messageFromClient.split("\\s+");
                System.out.println(this.name + ":" + arr[0]);

                switch (arr[0]){
                    case "登录":
                        break;
                    case "上传文件":
                        uploadFile();
                        break;
                    case "下载文件":
                        downloadFile();
                        break;
                    case "新增用户":
                        if(addUser())
                            break;
                        else{
                            output.writeObject("新增用户失败");
                            continue;
                        }
                    case "删除用户":
                        if(delete())
                            break;
                        else{
                        output.writeObject("删除用户失败");
                        continue;
                    }
                    case "修改用户":
                        if(updata())
                            break;
                        else{
                            output.writeObject("修改用户失败");
                            continue;
                        }
                    case "修改密码":
                        if(changepwd())
                            break;
                }
                // 回传消息
                output.writeObject(arr[0]);
                output.flush();


            } while (!arr[0].equals("退出登录")); // 只要未登出反复循环监听

            // 回传登出消息
            output.writeObject(messageFromClient);
            output.flush();
            connection.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        try {
            // 创建服务器对象
            DataProcessing.connectToDatabase();
            server = new ServerSocket(8000);
            outputToClients = new ArrayList<ObjectOutputStream>();
            System.out.println("\n等待连接...\n");
            // 反复循环实现不断接收用户的效果
            while (true) {
                // 反复等待
                Socket connection = server.accept();
                // 编号增加
                counter++;
                System.out.println("Thread " + counter + ":已连接" + connection.getInetAddress().getHostName());
                // 新增线程
                Thread t = new Server(connection, "Thread " + counter);
                // 使线程进入就绪态,一旦有CPU资源,将直接进入run()方法
                t.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private synchronized void uploadFile() {
        try{
            String []arr = messageFromClient.split("\\s+");//分割多个空格
            String ID = arr[1];
            String creator = arr[2];
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            String description = arr[3];
            String filename = arr[4];
            byte[]buffer = new byte[1024];
            int length = 0;
            DataInputStream dis = new DataInputStream(connection.getInputStream());
            File file = new File(DataProcessing.uploadpath+filename);
            FileOutputStream fos = new FileOutputStream(file);
            while((length=dis.read(buffer))>0){
                fos.write(buffer, 0, length);
                fos.flush();
            }
            DataProcessing.insertDoc(ID,creator,timestamp,description,filename);
            dis.close();
            fos.close();
        }catch(IOException | SQLException e){
            e.printStackTrace();
        }

    }

    private synchronized void downloadFile() {
        try{
            String []arr = messageFromClient.split("\\s+");//分割多个空格
            String Allfilename = arr[1];
            byte[]buffer = new byte[1024];
            int length = 0;
            File upfile = new File(Allfilename);//下载文件所在地
            FileInputStream fis = new FileInputStream(upfile);
            DataOutputStream dos = new DataOutputStream(connection.getOutputStream());

            while((length=fis.read(buffer))>0){
                dos.write(buffer, 0, length);
                dos.flush();
            }
        }catch (IOException e){
            e.printStackTrace();
        }

    }

    private synchronized boolean addUser() {
        try{
            String []arr = messageFromClient.split("\\s+");//分割多个空格
            String username = arr[1];
            String password = arr[2];
            String role = arr[3];
            DataProcessing.insertUser(username, password, role);
        }catch( SQLException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    private synchronized boolean delete() {
        try{
            String []arr = messageFromClient.split("\\s+");//分割多个空格
            String username = arr[1];
            DataProcessing.deleteUser(username);
        }catch (SQLException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    private synchronized boolean updata() {
        try{
            String []arr = messageFromClient.split("\\s+");//分割多个空格
            String username = arr[1];
            String password = arr[2];
            String role = arr[3];
            DataProcessing.updateUser(username, password, role);
        }catch (SQLException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }
    private synchronized boolean changepwd(){
        try{
            String []arr = messageFromClient.split("\\s+");//分割多个空格
            String username = arr[1];
            String password = arr[2];
            String role = arr[3];
            DataProcessing.updateUser(username, password, role);
        }catch (SQLException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }
}

```