【JAVA】 Socket is closed

本文讲述了在服务端和客户端文件传输中,如何正确管理输入输出流以防止Socketisclosed错误。强调了在接收或发送完成后,不应立即关闭相应的流,以确保数据完整传输并防止进程阻塞。
摘要由CSDN通过智能技术生成

在服务端和客户端之间既有接收又有发送的情况下,不要过早的关闭输入/出流。
如下:

服务端的IO流有:

  • 输出到磁盘的输出流1
  • 从客户端读取的输入流2
  • 向客户端输出的输出流3

客户端的IO流有:

  • 从磁盘读取的输入流4
  • 输出到服务端的输出流5
  • 从服务端读取的输入流6

服务端接收完客户端发送的图片后,可以关闭输出到磁盘的输出流,但是不要直接关闭接收客户端的输入流,即使已经接收完了。
同样,客户端发送完图片后,可以关闭从磁盘读取的输入流,但是不要关闭输出到服务端的输出流,即使已经发送完了。
否则,服务端或客户端会报错: Socket is closed。

猜测原因是不关闭IO流的话会阻塞另一端,使其不提前结束进程。
如下所示:服务端接收完图片向客户端发送“收到图片”,如果客户端此时已经关闭了输出流5,那么服务端发送完就可以直接关闭socket,结束进程了。而此时客户端可能还没有接受完“收到图片”,所以报错。而客户端在接收完“收到图片”后再关闭输出流5,服务端由于等待输入流2而阻塞,不会关闭socket,保证了客户端顺利接收。
初次学习,理解不深刻,如果有大佬能替我解惑不胜感激~!

// 服务端
public class TCPFileUploadServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);
        Socket socket = serverSocket.accept();
        String file_path = "tarimg\\2.jpg";
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file_path));
        int readLen = 0;
        byte[] buf = new byte[1024];
        while((readLen = bis.read(buf))!=-1){
            bos.write(buf,0,readLen);
        }
        bos.flush();
        bos.close();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("收到图片");
        bw.newLine();
        bw.flush();
        socket.shutdownOutput();

        bis.close();
        bw.close();

        socket.close();
        serverSocket.close();
        System.out.println("已发送");

    }
}

//客户端
public class TCPFileUploadClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        String file_path = "srcimg\\1.jpg";
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file_path));
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        byte[] buf = new byte[1024];
        int readLen = 0;
        while((readLen = bis.read(buf))!=-1){
            bos.write(buf,0,readLen);
        }
        bos.flush();
        bis.close();

        socket.shutdownOutput();
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String s = br.readLine();
        System.out.println(s);
        bos.close();
        br.close();
        socket.close();

    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值