李国帅 写于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流程,这样才会正常。
所以很多时候,客户端是很无奈的,你以为是自己的问题,结果害死了自己.
如果不了解服务器,很容易把服务器的错误引导到客户端,这并非技术的问题,而是交流的问题.
如果是交流的问题,他人的问题,你自己做再多的研究和排错都不可能解决问题,交流的问题还是需要交流来解决.
String json = null;
try {
json = reader.readLine();
} catch (IOException e) {
// e.printStackTrace();//说明socket断开了
MyLog.w(TAG, "socket recv fail exit for " + e.getMessage());
break;
}
if (json == null) {
sleepThread(50);
//这时候就应该考虑是服务器的问题了。
// MyLog.w(TAG, "socket receiveMsg exit for reader.readLine() ==
// null");
break;
}