PRE

在利用socket写通讯程序的时候,想检测服务器是否还活着。

从网上找了很多资料,都没有自己合适的,最后自己想了个办法,不过也相当于截取了心跳检测的一部分。

这里检测的是远程server的连接,而不是本地是否连接成功。首先想到socket类的方法isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,但经过试验并查看相关文档,这些方法都是本地端的状态,无法判断远端是否已经断开连接。

而有一个方法sendUrgentData,查看文档后得知它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节。

或者,其实如果断开连接了,你发送过去的数据会收不到,最后client会抛出io异常。

但是,上面两个方法,抛出异常的时间长达15秒!简直不能忍。

解决思路

当然,这里的需求环境是:发送数据次数非常少,几乎只需要判断一两次,数据是集中发送的。那么,就可以这样了:

只要client在发送数据前,先发送自定义的一个测试数据,并自定义一个String之类的变量(初始值null)来接收server发回的数据,client发完测试数据,睡500毫秒(自定义时间)(异步接收服务器消息),然后立刻检测这个string是不是null,就可以知道server是否收到消息了。

代码

客户端APP上的部分代码


/**客户端线程,用来建立连接和发送消息 */
public class Client implements Runnable{
Socket s=null;
DataInputStream dis=null;
DataOutputStream dos=null; private boolean isConnected=false;
Thread receiveMessage=null;
/**发送消息
* @param str 发送的信息,client仅向server发送两次消息,这是我自己的应用需求,根据实际情况来做你的。
* @throws IOException
* */
public void sendMessage(String str) throws IOException{
dos.writeUTF(str);
dos.flush();
} /**断开连接*/
public void disConnect(){
try {
dos.close();
dis.close();
s.close();
} catch (IOException e) {
System.out.println("client closed error");
e.printStackTrace();
}
}
/**建立socket连接,开启接收数据线程 * */
public void run() {
try {
s=new Socket(SERVER_HOST_IP,SERVER_HOST_PORT);
s.setOOBInline(true);
dis=new DataInputStream(s.getInputStream());
dos=new DataOutputStream(s.getOutputStream());
System.out.println("connected!");
isConnected=true;
receiveMessage=new Thread(new ReceiveListenerThread());
receiveMessage.start();
//发送imei
sendMessage(IMEI);
} catch (UnknownHostException e) {
System.out.println("fuwuqoweikaiqi");
e.printStackTrace();
} catch (IOException e) {
System.out.println("ioerr");
e.printStackTrace();
}
} private class ReceiveListenerThread implements Runnable{
//这一部分接收数据的处理,请根据实际情况修改
String data[]=new String[3];
public void run() {
try {
if(isConnected){
String receivedMessage=dis.readUTF();
System.out.println(receivedMessage);
serverStarted=true;
data=receivedMessage.split("_");
isLegal=Integer.parseInt(data[0]);
num1=Integer.parseInt(data[1]);
num2=Integer.parseInt(data[2]);
System.out.println(""+isLegal+num1+""+num2);
}
if(isConnected){
finalOK=dis.readUTF();
}
}catch (SocketException e){
System.out.println("exit!");
} catch (IOException e) {
e.printStackTrace();
}
} }

调用:

Client client=null;
/**客户端网络线程*/
Thread tClient=null;
client=new Client();
tClient=new Thread(client);
tClient.start();

服务器上:


/** 这是服务器用来接收处理客户端的线程类 */
class Client implements Runnable {
private Socket s;
private DataInputStream dis = null;
private DataOutputStream dos = null;
private boolean isConnected = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
isConnected = true;
} catch (IOException e) {
System.out.println("on clients' data in and out have error");
// e.printStackTrace();
}
}
public void run() {
String str;
try {
// 先检查是否是合法的客户端
while (isConnected) {
str = dis.readUTF();
str = dis.readUTF();
//此处的具体代码省略
dos.writeUTF("ok");
dos.flush();
}
}
} catch (EOFException e) {
System.out.println("Client closed");
Home.appendMessage((legalNum + 1) + "号客户端已经登出");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (dis != null)
dis.close();
if (dos != null)
dos.close();
if (s != null)
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

客户端判断服务器是否还活着代码:

try {
//客户端发送一个测试信息
client.sendMessage(cookie);
System.out.println("send");
//睡1秒
SystemClock.sleep(1000);
//这个finalok是在客户端的接收线程那里处理的。如果不是null说明服务器没问题
if(finalOK!=null){
client.disConnect();
exit("感谢您的使用,本次已经结束~");
}else{
throw new IOException() ;
}
//超时检测
} catch (IOException e) {
new AlertDialog.Builder(MainActivity.this).setTitle("提示").setPositiveButton("好的", null).setMessage("服务器关闭了,请联系管理员并在服务器重新开启后再次点击【发送】来提交数据").show();
client.disConnect();
e.printStackTrace();
}

后记:

当初只是简单记录了下自己的想法,写的很简陋,没想到慢慢这篇文章还好多人看,深感不安,故更新补充一下。

2015.3.27

声明:

文章若无说明转载,均为原创,如需转载,请注明出处!

JAVA ANDROID SOCKET通信检测(SERVER)连接是否断开的更多相关文章

  1. Android简单实现Socket通信,client连接server后,server向client发送文字数据

    案例实现的是简单的Socket通信,当client(Androidclient)连接到指定server以后,server向client发送一句话文字信息(你能够拓展其他的了) 先看一下服务端程序的实现 ...

  2. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  3. java的socket通信

    本文讲解如何用java实现网络通信,是一个非常简单的例子,我比较喜欢能够立马看到结果,所以先上代码再讲解具体细节. 服务端: import java.io.BufferedReader; import ...

  4. Java的Socket通信----通过 Socket 实现 TCP 编程之多线程demo(2)

    JAVA Socket简介 所谓socket 通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过”套接字”向网络发出请求或者应答网络请求. import java.io ...

  5. 分析一个socket通信: server/client

    分析一个socket通信: server/client1 server 1. 创建一个server_socket文件,并绑定端口,然后监听端口 (socket, bind, listen) 2. 查询 ...

  6. Android Socket通信详解

    一.Socket通信简介  Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客 ...

  7. Android Socket 通信

    Android socket 通信 安卓编写Socket客户端,实现连接Socket服务端通信. 创建Socket连接并获取服务端数据 先创建几个全局变量吧 private BufferedWrite ...

  8. 浅谈android Socket 通信及自建ServerSocket服务端常见问题

    摘  要:TCP/IP通信协议是可靠的面向连接的网络协议,它在通信两端各建立一个Socket,从而在两端形成网络虚拟链路,进而应用程序可通过可以通过虚拟链路进行通信.Java对于基于TCP协议的网络通 ...

  9. Android Socket通信编程

    安卓客户端通过socket与服务器端通讯一般可以按照以下几个步骤:(1).通过IP地址和端口实例化Socket,请求连接服务器:socket = new Socket(HOST, PORT); //h ...

随机推荐

  1. 使用Win32 API创建不规则形状&带透明色的窗口

    前一阵突然想起了9月份电面某公司实习时的二面题,大概就是说怎么用Win32 API实现一个透明的窗口,估计当时我的脑残答案肯定让面试官哭笑不得吧.所以本人决定好好研究下这个问题.经过一下午的摸索,基本 ...

  2. BZOJ 1088 扫雷Mine (递推)

    题解:如果确定了第一排前两个数,那么剩下的数是唯一确定的,所以只要分情况讨论即可. #include <cstdio> #include <cstring> int n,a[1 ...

  3. vs2013 linq to mysql

    安装文件 1.下载安装文件 2.创建项目 3.创建mysql数据连接 4.新建ADO.NET数据模型 项目实现代码 using (WorkerContainer db = new WorkerCont ...

  4. 人生新开始——第一天上班

    今天是我正式上班的第一天,对今天要做的工作充满期待,对将要面对的同事们也充满期待.这天起的很早,7点钟就开始睡不着了,忙着起来整理东西,看着时间还早,便打开电脑听起CNN News,练习听力,一听就听 ...

  5. 令人作呕的OpenSSL

    在OpenSSL心脏出血之后,我相信非常多人都出了血,而且流了泪...网上瞬间出现了大量吐嘈OpenSSL的文章或段子,仿佛内心的窝火一瞬间被释放了出来,跟着这场疯闹,我也吐一下嘈,以雪这些年被Ope ...

  6. 初探swift语言的学习—Object-C与Swift混编

    swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. ...

  7. hdu3416 Marriage Match IV【最短路+最大流】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4297581.html   ---by 墨染之樱花 题目链接:http://acm.hdu.ed ...

  8. Onvif协议

    ONVIF致力于通过全球性的开放界面标准来推进网络视频在安防市场的应用,这一接口界面标准将确保不同厂商生产的网络视频监控产品具有互通性.2008年11月,论坛正式发布了ONVIF第一版规范ONVIF核 ...

  9. NOIP2015酱油记

    day0 坐动车到广州..下午就在酒店颓... day1 早上6:30起床...大概8:00到六中..ZSJZ众貌似很晚才到..毕竟他们酒店就在学校门口(真的就刚刚好是门口...),大概8:15进去机 ...

  10. debian6 更新python版本到python3.3

    1.下载python3.3安装包 #wget wget --no-cookie --no-check-certificate --header "Cookie:gpw_e24=http%3A ...