Java Socket 如何判断客户端断开

hehebw 2010-01-30 04:08:48
我做了个多线程的服务器程序 线程中等待客户端的消息 部分代码如下:

boolean done=clientRequest.isConnected();//判断客户端Socket是否连接

while(done)//客户端是连接的
{
try
{
input = clientRequest.getInputStream();
Binput = new BufferedInputStream(input);
str = "" + Binput.read();
if(Binput.read()!= -1)//如果客户端有消息就打印出来
{
System.out.println(str);
}

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

if(clientRequest.isclosed())//判断Socket是否关闭
{
done=false;//如果关闭,就跳出无限循环(while)
}
}

我的代码能实现服务器与客户端的通信
问题是: 当客户端中断或退出 以上代码却不能判断Socket中断 跳不出while的无限循环
请哪位大侠指点一二 小弟不慎感激......
...全文
7019 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
read 读到 -1 时,客户端就关掉了
haizhixiang 2010-04-27
  • 打赏
  • 举报
回复
用那个什么Is什么的都没有用的!
haizhixiang 2010-04-27
  • 打赏
  • 举报
回复
很简单,加一个读取Buffer的函数read,这是个阻塞函数,用 cSocket.setSoTimeout(2000)来设定其超时时间,抛出错误,判断其返回值,如果返回值不大于0,则表示客户端已经断开。
hehebw 2010-02-01
  • 打赏
  • 举报
回复
谢谢各位 大侠的回复 我搞定了 总结一下:
1. while(Binput.read()!= -1) 这种方法 能判断出客户端输入是否为空 客户端断开 能跳出死循环
但是 我想得到的数据却从第二个开始了 所以这方法不适宜

2. 用下面的方法就没问题了 在死循环中加入以下代码
try {
socket.sendUrgentData(0);
} catch (IOException e) {
done= false; //如果抛出了异常,那么就是断开连接了 跳出无限循环
}

10楼 16楼说的没错 12楼说的情况我暂时没有遇到
谢谢 散分...
YBBPS1109 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 inhibitory 的回复:]
从客户端的输入流里读出的是null, 这时就说明客户端已经断开.
[/Quote]
+
try {
socket.sendUrgentData(0);
} catch (IOException e) {
//如果抛出了异常,那么就是断开连接了

}
fhuibo212 2010-02-01
  • 打赏
  • 举报
回复
跟帖拿分
舷Kelvin 2010-02-01
  • 打赏
  • 举报
回复
捕获的应该是流获取不到的错。

运行的时候最长的时间应该是阻塞在从流里获取数据的地方,断开的时候程序一般也都停在这里,监听这里就行了,我自己做过这样的东西,就是这么处理的,isConnected基本没用。
hehebw 2010-02-01
  • 打赏
  • 举报
回复
23楼 没有别的办法了吗? 重新开个Socket 那是不是要重新开线程啊? 那我怎么跳回到线程的开始呢?

24楼 问题是捕获不到断开时的报错啊
舷Kelvin 2010-02-01
  • 打赏
  • 举报
回复
进了循环体以后如果断了,isConnected判断就判不出来了,只能下次开始循环的时候检查,还是拿报错来判断的好。

代码没细看。还有什么问题再问吧。
qqbz 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 hehebw 的回复:]
19楼
1.对 网络设备在断开时是不会发送消息给服务器的 
2.无论先启动设备还是先启动我的服务器 都能正常连接 也能正常收到设备的数据 
问题是:当设备断开时 我却不知道如何判断它断开了?
[/Quote]

如果是这样的话,你就不要判断那个网络设备断来了,因为当网络设备断开时候是没有消息发送给服务器的,而此时服务器正等待网络设备发送。当网络设备第二次连接上来时候,服务器就会抛异常,原因是已经不是第一次的网络连接了,所以你需要做的,当收到上面那个异常后,就重新启动一个新的socket(由于我问的第二点,无论先启动哪个都能正常连接,所以这样做是可以的)
andyjins 2010-02-01
  • 打赏
  • 举报
回复
while(true) {
try{
in.read();
}
catch(Exception e) {
in.close();
socket.close();
break;
}
}

我都这样写,没遇到什么问题!
黎某人 2010-02-01
  • 打赏
  • 举报
回复
catch (Exception e) {
System.out.println("客户机:"+socket.get忘记了+"离开了");
return;
}
hehebw 2010-02-01
  • 打赏
  • 举报
回复
19楼
1.对 网络设备在断开时是不会发送消息给服务器的
2.无论先启动设备还是先启动我的服务器 都能正常连接 也能正常收到设备的数据
问题是:当设备断开时 我却不知道如何判断它断开了?
qqbz 2010-02-01
  • 打赏
  • 举报
回复
楼主,你18楼出现情况是正常的,如果要解决该问题,请确认:
1.当关闭网络设备后,是否有什么消息会发给你的服务端程序?从你以上描述看,应该是断就断了,没有反应了。
2.是否先要启动你的服务端程序,再启动那个网络设备?如果先启动网络设备,再启动你服务器会有什么结果?

hehebw 2010-02-01
  • 打赏
  • 举报
回复
貌似还是有问题啊 就是开始用 teinet命令去连接我的服务器 然后关闭dos命令窗口 代码能跳出无限循环
但是我去关闭我的设备时 就没什反应 我再次连上设备后 Java出错信息是:
java.net.SocketException: Connection reset
麻烦给点意见
Inhibitory 2010-01-31
  • 打赏
  • 举报
回复
抛异常或者从客户端的输入流里读出的是null, 这时就说明客户端已经断开.
一般情况下, 客户端断开都能读到一个null.
humanity 2010-01-31
  • 打赏
  • 举报
回复
if(Binput.read()!= -1)//如果客户端有消息就打印出来

这句返回 0 和 -1 类似意思不一样,你试试看。
树成 2010-01-31
  • 打赏
  • 举报
回复
设置延迟断开,这需要拥有监控线程。曾经很多人利用这种特性攻击过HTTP服务器,后来用延迟断开解决这个问题的。
Mybeautiful 2010-01-31
  • 打赏
  • 举报
回复
try {
socket.sendUrgentData(0);
} catch (IOException e) {
//如果抛出了异常,那么就是断开连接了

}

就是所谓的心跳测试,但是在本人实践中,发现它并不总是凑效。 有时候明明测试过了,但是就是发不出数据,也读不到,最终time out.

yuhuidog 2010-01-30
  • 打赏
  • 举报
回复
以上方法都是没用的!
try {
socket.sendUrgentData(0);
} catch (IOException e) {
//如果抛出了异常,那么就是断开连接了

}
加载更多回复(9)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧