天天看点

编写Java网络程序,最好不要片面的考虑一个方面,最好多方面一起看。

李国帅 写于2018/4/24 13:45:48

1、道听途说的方法可能导致程序混乱,最好弄清楚再使用

网上有人说,java可以使用socket.sendUrgentData来判断连接情况,如果是非阻塞的,会通过异常判断是否断线

但是经过实际的测试,如果没有服务端的配合,仅仅客户端这么做会有问题。

经常的情况,有多人去写通信程序,不能预知对方的操作,只能使用最通用的流程,不能做这种旁门左道的事情。

    try {

         socket.sendUrgentData(0xFF);

     } catch (Exception e) {

         String errMsg = e.getMessage();

         // sendto failed: EPIPE (Broken pipe) 连接中断

         MyLog.w(TAG, "socket server fail exit for " + errMsg);

         // if (errMsg.toLowerCase().contains("broken pipe")) {

         // }

     }

除此之外,网上的很多答案也大都是无效的东西,除了浪费时间恐怕没什么作用。

2、网络程序并不能独立的一侧,需要对方一侧并且综合考虑业务逻辑。

实际中,到底如何做还需要根据具体的业务应用,在我们的程序中,进行了如下的逻辑:

在进行socket消息收发之前必须发送"online"消息,否则发送任何消息都毫无下文。并且调用reader.readLine()接收直接返回null,就是因为总是接收到null一直调试了一天而不清楚原因,这就是因为不了解服务器的收发逻辑,没有安装收发流程进行编码,导致发送和接收在业务逻辑上不对应,并不是技术的原因。

        // 发送验证,判断socket是否正常

         writer.println(strMessage);//发送上线消息

        String json = null;

         try {

             writer.println("#");

             writer.flush();

             json = reader.readLine();

         } catch (IOException e) {

             // e.printStackTrace();

             MyLog.w(TAG, "socket:recv fail after send online, exit for " + e.getMessage());

         }

         MyLog.w(TAG, "socket recv json=" + (json==null?"null":json));

根据业务逻辑正常,第一次就能够正常的收发数据。

第二次,如果直接重新连接socket端口,还是出现reader.readLine() == null的情况,实在无奈,结果重新登录业务服务器,登录成功结果发现readLine正常。

后来发现原来socket断开的时候,业务逻辑部分也关闭了,必须重新启动业务逻辑和socket流程,这样才会正常。