[java基础复习]网络编程传输序列化文件

本文探讨了如何在图书管理系统中利用网络传输和多线程技术实现序列化文件的高效传输,重点讲述了服务器端处理文件读写时遇到的`Socketclosed`异常,以及解决方法——仅关闭最大级别的流资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前作业有一个问题是说给一个图书管理系统编写使用网络传输+多线程的实现方法来完成序列化文件传输。做法其实跟序列化差不多,这里记一些遇到的错误:

服务端代码
package com.java.Server;
import com.java.DAO.ExpressDAO;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    static int client_num = 0; //当前连接的客户端数量
    public static void main(String[] args) throws IOException {
        int port_num = 5555; //端口号
        final String filePath = "DAO.txt";
        ServerSocket serverSocket = new ServerSocket(port_num);
        System.out.println("服务器已经启动,端口号为:"+port_num);
        //无限循环用于接收新来的client
        //这里用do while循环,当客户端使用人数为0的时候就结束服务端
        do{
            //与客户端连接,建立socket
            Socket socket = serverSocket.accept();
            client_num++;
            System.out.println("当前客户端连接数量为:"+client_num);
            new Thread(){
                @Override
                public void run() {
                    try{
                        //先建立socket的输出流,因为socket只实现了这个方法
                        OutputStream os = socket.getOutputStream();
                        //因为要写的是序列化的文件,所以这里使用ObjectOutputStream(os)
                        ObjectOutputStream socket_oos = new ObjectOutputStream(os);
                        //接下来是序列化标准流程,先用ObjectInputStream读一个file,
                        // 然后转换file成特定形式的object,然后向客户端写过去这个object
                        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("DAO.txt"));
                        ExpressDAO expressDAO = (ExpressDAO) ois.readObject();
                        socket_oos.writeObject(expressDAO);
                        //socket_oos.close();
                        ois.close();

                        //从客户端那边读过来更新的文件,然后写进DAO.txt
                        InputStream is = socket.getInputStream();
                        ObjectInputStream socket_ois = new ObjectInputStream(is);
                        ExpressDAO express = (ExpressDAO) socket_ois.readObject();
                        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("DAO.txt"));
                        oos.writeObject(express);
                        //socket_ois.close();
                        oos.close();


                    }catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                    client_num--;
                    System.out.println("有一个线程退出,目前剩余"+client_num+"线程");
                }
            }.start();
        }while(client_num != 0);
        System.out.println("服务器结束");
    }
}

在服务器端我注释了两行代码,分别是socket_ois.close();和socket_oos.close();
因为如果不注释掉会出现以下报错

java.net.SocketException: Socket is closed
	at java.net.Socket.getInputStream(Socket.java:903)
	at com.java.Server.Server$1.run(Server.java:40)

查了一下StackOverflow发现问题其实是因为如果我关闭了不管是socket的输入流还是输出流都会导致整个socket关闭,所以如果后续还有数据传输发生就会出现这种报错。
原文:
A ‘Socket closed’ exception means that the application that caught the exception closed the socket and then kept trying to use it. Please note that closing the input or output stream of a socket closes the other stream and the socket as well. According to your statements seems you close the stream before using the socket to send data.

于是我点进去了ObjectOutputStream.close()的源码看了看,发现源码的意思是调用该方法,任何和他涉及到的相关资源也会关闭。所以说我原来以为我只是想关闭oos,没想到把socket的outputStream也关了。但是也了解了如果我要关闭,我关闭最大的即可。

/**
* Closes the stream. This method must be called to release any resources
* associated with the stream.
*
* @throws  IOException If an I/O error has occurred.
*/
public void close() throws IOException {
   flush();
   clear();
   bout.close();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值