java的socket多线程编程之关闭socket

本文介绍了如何在Java中优雅地关闭Socket连接,通过用户点击断开按钮发送关闭消息,服务器确认后依次关闭连接,避免异常关闭。详细探讨了关闭顺序、线程交互以及可能遇到的问题,包括接收线程和主程序中Socket关闭的相互影响。
摘要由CSDN通过智能技术生成

这两天在写socket通信,也就是下面的东西,然后遇到了个问题,怎样才能优雅的关闭socket(正常关闭而不是发生异常导致的关闭)
在这里插入图片描述
直接说思路吧,后面再说我遇到的问题!

我们这里说的关闭是用户点击断开按钮后再关闭,如果是用户直接退出程序可以在退出之前调用和关闭按钮一样的方法,或则采用心跳检测判断用户是否在连接,不过这里不说怎么实现这个。

我们一般只说客户端断开连接,如果想要服务器断开和客户的连接也可以采用同样的方法,但是实际情况服务器是一直运行的,所以我们说客户端的就行。

思路
1、我们在点击断开连接按钮时并不是直接关闭socket,而是先给服务器发送断开连接消息;
2、服务器收到该消息后再向客户端发送确认消息;
3、服务器发送完确认消息之后断开连接;
4、客户端收到确认消息后再断开连接;
5、为了能够再次连接,客户端还要在主程序中关闭socket。(为什么要再次关闭可以看我后面的问题)

其实看到上面的思路应该知道怎么做了,只是很多时候我们没有想到是这样,然后直接关闭socket,虽然可以关闭,但是那时因为发生了异常,你不关闭程序也会帮你关闭。至于为什么会异常,很简单,在接收线程里面是一个死循环,它一直在监听服务器有没有给它发消息,当你关闭socket的时候你无法进入这个循环去关闭它,但是会影响到它使它为空或者突然被关闭(正在监听突然被关闭是有异常的)。

下面以我的代码为例:

主要看三个类
接收线程:一直在监听,为了使接收和发送不相互影响必须使用线程
发送线程:这个其实和普通类一样,因为只有在有需要的时候才发送,这时调用该类里面的发送方法即可,如果是控制台的话那它就必须线程,否则不能使发送和接收分离
主类:用于创建连接和关闭连接
在这里插入图片描述
1、当我们点击关闭按钮时,只需要给服务器发送一个关闭消息:readyCloseLink(),它会调用发送线程的发送方法给服务器发送断开连接消息bye

/**
     * @Name
     * @Description  TODO 准备关闭,在点击关闭后并没有实际关闭,
     * 而是给服务器发送关闭消息,服务器收到后返回确认消息,同时服务器关闭该连接
     * 客户端接收到确认后接收线程中关闭socket,最后在本类中再次关闭socket以保证可以再次连接
     * (接收线程中关闭socket并不能关闭本类的socket,在接收线程中关闭是为了程序正常退出而不是因为异常退出)
     * @param
     * @Return void
     * @Author KingSSM
     * @Date 2019/12/5 9:22
     */
    public void readyCloseLink(){
   
        new SendThread().closeClientSocket("bye");
    }

    //真正断开连接,此类中的socket置空,发送线程的clientSocket已经关闭,此处关闭可以确保可以再次连接
    public void closeLink() {
   
        try {
   
            if (socket != null) {
   
                socket.close();
            }
            socket = null;
        } catch (IOException e) {
   
            e.printStackTrace();
        }
        System.out.println("<====== 警告:已断开连接 ======>");
        uiUpdate.receiveMessage("<====== 警告:已断开连接 ======>")
  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值