我在C下面写程序,如果对面的socket主动关闭,会发一个0长度的数据包,本地可以判断出来。如果是网络问题,比如拔了网线,这个时候是没有对方给你发的包的。处理办法是通过发送测试线路的报文(当然和对方有约定)查看是否有返回结果数据。还一个办法是设置linger的一个什么参数,让底层自动多久侦测一下线路状况,具体的就看Java里面有没有了。

解决方案 »

  1.   

    如果socket已经断开,任何一方的read操作都会抛出异常!!
      

  2.   

    to GJA106(中文字符):
      我现在正好碰到这个问题,服务端主动断掉但是我的客户端怎么read都没有抛出异常
    read操作不一定抛出异常吧,但是write肯定会抛出异常的
      

  3.   

    那如果对方断开,read会不会抛出异常呢??
    下午的时候碰到一个奇怪的问题,就是server端断开后我write一个buffer竟然还可以发送并且没有抛出异常(当然server端肯定没收到),一定要等到write第二个buffer的时候才抛出异常broken pipe的异常,究竟怎么回事??哪位能给点提示??
      

  4.   

    补充一点,(在java里)read方法是查不到异常的,因为read是个异步过程.
    其实,当TCP包到达后,就放入你这端的缓冲区中,read是读缓冲区的数据,
    而不是说,通知另一端,我要读你的数据了,因为read读到的数据是另一端
    过来的,发不发送是另一端控制的.在这个时候,java本身的实现是不知道
    缓冲区是不是有效,它只管从中读取数据.
    当然,如果关闭自己这段的连接,就意味着缓冲区被注销,这时再read,绝对
    有异常出来了.
    顺便再加一点,很多的这种通信程序都有所谓的心跳检测,来进行判断,实际
    上就是定时发送检查链路是否可达的TCP包.
      

  5.   

    下午的时候碰到一个奇怪的问题,就是server端断开后我write一个buffer竟然还可以发送并且没有抛出异常(当然server端肯定没收到),一定要等到write第二个buffer的时候才抛出异常broken pipe的异常,你说的这个问题有些奇怪,按道理讲是不应该的.检查一下你server端的程序代码,看看是否在
    其关闭时没有释放完资源,在java中,显式地调用资源,需要显式地释放.
    你做个这样的测试嘛,你把网线拔掉,再发包给sever端,看是不是在第二个buffer时异常才出来.
      

  6.   

    我现在也有心跳检测,可是还得实现重联机制,就是说任何断了的情况下都必须重新尝试连接,所以我必须实时得到连接状态,但是要得到真正的实时连接状态的画就必须用write或者read(楼上的已经说了read是不能检测到连接状态的)来发送或者接收数据然后捕捉异常来判断,所以问题就来了,由谁来发出数据来启动重联机制,如果由真正的数据(客户端提交的数据)来触发的话那么这条数据肯定不能发送过去,而是要等待第二条才有可能发送出去,而心跳是定时发送,所以由心跳来触发异常似乎也不太好,而且刚才上面也说了我用write的时候要write两次才能得到异常,这个问题究竟是怎么回事呢??
      

  7.   

    楼上说的测试我明天上午会进行,所以具体情况要明天上午才能知道,我重连之前会将所有ouput、input还有socket都关掉并且置null,应该不会有问题,我也觉得这个问题挺奇怪的,测试了一天都没什么结果,server端是用c++写的,由于不是我写的我也不知道它是用什么方式断开连接的,明天测试会同时用netstat命令检测网络连接状态,希望会有进展