记录实现socket聊天室的过程
发布于2020-01-07 23:25:23,更新于2020-06-15 11:43:57,标签:java 文章会持续修订,转载请注明来源地址:https://meethigher.top/blog整了一天,思路写得乱七八糟,最后把所有代码推翻重写。
为了让思路能够清晰一点,还特意把服务端跟客户端进行交互的过程图给画了下来。
最后,按着这个图,慢慢地研究出来了。
附上效果图。
看上去很完美了吧!
但是!
如果此时有任意一个客户端退出,服务端就会报错Connection reset
,出现这个问题,是因为客户端关闭了连接,但是此时的服务端,还在读取数据,由此导致了错误(我是这样理解的)。
那么,如何让服务端判断客户端关闭连接了呢?并在客户端关闭的时候,加上一句提示xxx退出聊天室
。
360了一下,发现需要用到java心跳技术。
我要去学啦(此时时间2020-1-5 20:43)
发现根本不是心不心跳的问题(2020-1-7 21:14)
今天终于整明白了。
参考文章关于客户端断开连接后服务器抛出异常Connection reset
java.net.SocketException:Connection reset
原因:
客户端关闭后,socket断开了,但是服务器为客户端开启的线程还在执行。所以要处理一下异常。
在为客户端开启的线程里面定义一个布尔型变量,isOnline=true,在为客户端监听时while(true)修改为while(isOnline),如果出现异常,即客户端退出,isOnline赋值为false
java.net.SocketException:Socket is closed
原因:
服务端不知道客户端socket已经关闭,如果继续发送数据,可能导致发送如上关闭异常。如果有多个客户端长连接给服务端建立,异常处理不恰当的话,还可能引起下次发送异常关闭情况。
socket客户端端来之后,回调服务端socket,这时服务端发现输入流的长度为-1,这时首先需要关闭客户端socket,然后把该socket从发送列表中删除。
具体解决方案:
- 检查是否断开
1 | if(in.read(b,0,len)==-1){ |
- 关闭客户端socket并且移除发送客户端socket
1 | try{ |
最后的运行结果: