紧急求助:java网络通信问题

yanglei02152003 2009-03-24 11:18:13
问题描述:
建立一个TCP SOCKET,服务器端跑的是C程序,客户端是通过页面执行的JAVA APPLET程序。当服务器端断电,关闭了SOCKET,客户端的程序,偶调用socket.iscloesd(),值为false,调用socket.isconnect(),值为true,为什么socket还有连接呢?还没有关闭呢?但是服务端已经关闭了,很奇怪!
请各位大虾指点一二!

多谢,高分奉送
...全文
259 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanglei02152003 2009-03-30
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 jiangnaisong 的回复:]
4)若对方机器突然掉电,则你写操作后,低层TCP协议会将你的数据发给已掉电的服务器,当TCP报文超时时,低层TCP协议会重试多次,当超过一定次数时,你的checkError()才会检测到错误(即:错误不是马上就…
[/Quote]
的确如楼上所说,当服务器断电之后,不是马上就检测到出错。
偶已经试过了,在断电之后,调用checkError()是false,证明当时是没有错误的。
换句话说,也就是当服务器断电之后,我用checkError(),即时是检测不到SOCKET已经不存在,不能进行正常的读写了?
如果服务器端突然断电,我向输出流写数据的时候,怎样才能当时就知道不能正常通信了呢?只能用超时机制吗?
请LS指教!
多谢!
lliiqiang 2009-03-30
  • 打赏
  • 举报
回复
唯一的方法就是服务器要实时的隔一段时间就向客户端发送数据,例如每1秒发送一条数据,客户端不断的接到数据,从而知道连接没有断开。如果客户端在某个时间段没有接受到数据,那么证明与服务器断线了
yanglei02152003 2009-03-27
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 jiangnaisong 的回复:]
答:你要向服务器写数据啊.然后再用checkError()检测写操作是否发生了IO异常啊.
当服务器断电时:
1)你进行读数据操作.则可借助"读操作超时"来判断服务器是否可能不在线了
2)你进行写数据操作,则可借助 PrintStream 的checkError()来检测是否发生了IO异常
3)你不读,又不写只是静静地等待,则此时只有间隔了一个较长的时间后,TCP的保活定时器发生作用,你的程序才会得到网络产生异常.
[/Quote]

你说的写数据操作,请问是在写之前还是写之后用checkError(),偶在写之前检测是没有错误的,要在写之后吗?
偶多说的写就是
private OutputStream fOut1;
private PrintStream out1;
private Socket sock1;
...
try{
sock1=new Socket("192.168.0.224",6668);
}catch(SocketException e){
e.printStackTrace();
}
...
测试的的是下面的代码
try {
fOut1 = sock1.getOutputStream();
out1 = new PrintStream(fOut);
}catch(IOException e1){
e1.printStackTrace();
}
System.out.println(out1.checkError());
String com="111111eeee";
ou1.println(com);
就是上面这个标注为红色的语句
在之前还是之后呢?
之前没有效果
多谢!
云上飞翔 2009-03-27
  • 打赏
  • 举报
回复
就是上面这个标注为红色的语句
在之前还是之后呢?
之前没有效果
多谢!
答:
1)写操作必须放在前面.
2)先写,后用checkError()来检测
3)若对方机器在线,但已正常关闭了SOCKET,则checkError()能几乎立即检测到错误
4)若对方机器突然掉电,则你写操作后,低层TCP协议会将你的数据发给已掉电的服务器,当TCP报文超时时,低层TCP协议会重试多次,当超过一定次数时,你的checkError()才会检测到错误(即:错误不是马上就能检测到的,会有一个迟后,这是TCP低层重试多次的时间),因此:大部分情况下,不你做了几次写操作后,才会检测到前面的某一次写操作其实是失败的(即:checkError()的检测对于第4)情况是迟后的.)
yangkaixin1226 2009-03-26
  • 打赏
  • 举报
回复
帮顶一个
javause 2009-03-26
  • 打赏
  • 举报
回复
这个还有点不懂,不能帮忙了。
云上飞翔 2009-03-26
  • 打赏
  • 举报
回复
答:你要向服务器写数据啊.然后再用checkError()检测写操作是否发生了IO异常啊.
当服务器断电时:
1)你进行读数据操作.则可借助"读操作超时"来判断服务器是否可能不在线了
2)你进行写数据操作,则可借助 PrintStream 的checkError()来检测是否发生了IO异常
3)你不读,又不写只是静静地等待,则此时只有间隔了一个较长的时间后,TCP的保活定时器发生作用,你的程序才会得到网络产生异常.

yanglei02152003 2009-03-26
  • 打赏
  • 举报
回复

答:用PrintSream流的checkError()来检查低层SOCKET的OutputStream流的IOException.若有异常…
[/Quote]

偶按照你的说法,结果还是显示,当服务器端断电之后,没有任何异常出现,checkError()的值都是false,表示没有错误
贴出代码,
private OutputStream fOut1;
private PrintStream out1;
private Socket sock1;
...
try{
sock1=new Socket("192.168.0.224",6668);
}catch(SocketException e){
e.printStackTrace();
}
...
测试的的是下面的代码
try {
fOut1 = sock1.getOutputStream();
out1 = new PrintStream(fOut);
}catch(IOException e1){
e1.printStackTrace();
}
System.out.println(out1.checkError());

运行结果是,正常连接的情况下是没有错误和任何异常,服务器断电之后还是没有任何异常。
用的是同一个SOCKET,这个SOCKET在服务器断电前后是同一个,没有新建。
请楼上麻烦看一下!多谢
goodmrning 2009-03-25
  • 打赏
  • 举报
回复
帮顶一个!
yanglei02152003 2009-03-25
  • 打赏
  • 举报
回复
感谢楼上的答复
偶现在在从SERVER端读取数据时,已经设置了超时,并且能够捕获到异常
但是问题是如果SERVER端断电之后,偶再向SERVER端发送消息时,要怎样捕获这个异常处理呢?
我用的是PrintSream这个对象,好像它本身没有I/O异常处理,请指教!主要是捕获SOCKET不能正常通信这个异常。
云上飞翔 2009-03-25
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 yanglei02152003 的回复:]
感谢楼上的答复
偶现在在从SERVER端读取数据时,已经设置了超时,并且能够捕获到异常
但是问题是如果SERVER端断电之后,偶再向SERVER端发送消息时,要怎样捕获这个异常处理呢?
用的是PrintSream这个对象,好像它本身没有I/O异常处理,请指教!主要是捕获SOCKET不能正常通信这个异常
[/Quote]
答:用PrintSream流的checkError()来检查低层SOCKET的OutputStream流的IOException.若有异常,则表明网络通信出错了.
wuyongai0563 2009-03-24
  • 打赏
  • 举报
回复
可能需要一定的间隔吧。。。TCP是有连接的,服务器断电,没有向客户端通知状态。。。
关注ing。。。
云上飞翔 2009-03-24
  • 打赏
  • 举报
回复
那偶现在要怎样才能知道服务器断电之后SOCKET断开连接的情况呢?
偶现在只是想处理当服务器断电之后,客户端怎样才能知道,并且做出相应的处理,提醒用户SERVER端已经断开连接
多谢!

是不是一般不依赖于TCP的保活定时器啊?
那自己怎么设置它的保活机制呢?

答:1)一般不依赖于TCP的保活定时器,要自己定义一个"保活机制".

2)现在只是想处理当服务器断电之后,客户端怎样才能知道,并且做出相应的处理?
恰恰相反,这个问题更多的是:服务器方要知道,客户端断电之后,服务器怎样才能知道,并且释放客户机在服务器上登录后所占用的资源.(即:服务器方更需要对客户机方是否在线进行判断,以便释放相关的占用服务器的资源).

3)你的情况,方法很多.简单的做法可以是:只要在从socket上从服务器上读取数据时,设定超时选项,超时一到,就认为服务器不在线了(并不一定是真的不正线,如:服务器太忙了,没有响应).这是因为:向服务器写时,若服务器不在线,会有I/O异常出现的,你会获取到的. 这样无论是读,还是写,都可判断出了.
yanglei02152003 2009-03-24
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jiangnaisong 的回复:]
引用楼主 yanglei02152003 的帖子:
问题描述:
建立一个TCP SOCKET,服务器端跑的是C程序,客户端是通过页面执行的JAVA APPLET程序。当服务器端断电,关闭了SOCKET,客户端的程序,偶调用socket.iscloesd(),值为false,调用socket.isconnect(),值为true,为什么socket还有连接呢?还没有关闭呢?但是服务端已经关闭了,很奇怪!
请各位大虾指点一二!

多谢,高分奉送

答:socket.iscloesd()是检测你的so…
[/Quote]

是不是一般不依赖于TCP的保活定时器啊?
那自己怎么设置它的保活机制呢?
yanglei02152003 2009-03-24
  • 打赏
  • 举报
回复
多谢楼上各位给出的分析
那偶现在要怎样才能知道服务器断电之后SOCKET断开连接的情况呢?
偶现在只是想处理当服务器断电之后,客户端怎样才能知道,并且做出相应的处理,提醒用户SERVER端已经断开连接
多谢!
x_pengcheng 2009-03-24
  • 打赏
  • 举报
回复
学习
javacaspnet 2009-03-24
  • 打赏
  • 举报
回复
时间延迟,或者服务器配置
zhaojiubo 2009-03-24
  • 打赏
  • 举报
回复
真是奇怪了,
按理是应该被关闭了的,
难道是没有正常关闭吗(也就是close() 方法未被正常调用导致的??)


帮顶顶!!
mumu_java 2009-03-24
  • 打赏
  • 举报
回复
服务器突然断电,客户端是不会知道也没有时间知道服务器端的连接已经断掉了,所以在客户端还认为服务器端连接为正常,这从lz调用的那些方法的返回值就可以知道了.如果这时客户端在向服务器端发送请求,才会发现连接失败.
sjkof 2009-03-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sodino 的回复:]
在断电之前,socket.iscloesd(),值为false,调用socket.isconnect(),值为true,这些都是正确的.

楼主的疑问是服务器断电之后,然后调用客户端的isclosed()    isconnect(),这时,显然除了只是服务器断电了,并没有任何的动作作用到客户端,当调用函数测试客户端的状态,客户端并不是再向服务器发送消息以确定连接状态,而是直接调用断电之前客户端处的状态信息.所以调用得到的信息和断电之前还是一样的.

只是这里已经不能再发送任…
[/Quote]

支持
加载更多回复(4)

62,615

社区成员

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

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