JAVA ANDROID SOCKET通信检测(SERVER)连接是否断开
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)连接是否断开的更多相关文章
- Android简单实现Socket通信,client连接server后,server向client发送文字数据
案例实现的是简单的Socket通信,当client(Androidclient)连接到指定server以后,server向client发送一句话文字信息(你能够拓展其他的了) 先看一下服务端程序的实现 ...
- Flex通信-与Java实现Socket通信实例
Flex通信-与Java实现Socket通信实例 转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...
- java的socket通信
本文讲解如何用java实现网络通信,是一个非常简单的例子,我比较喜欢能够立马看到结果,所以先上代码再讲解具体细节. 服务端: import java.io.BufferedReader; import ...
- Java的Socket通信----通过 Socket 实现 TCP 编程之多线程demo(2)
JAVA Socket简介 所谓socket 通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过”套接字”向网络发出请求或者应答网络请求. import java.io ...
- 分析一个socket通信: server/client
分析一个socket通信: server/client1 server 1. 创建一个server_socket文件,并绑定端口,然后监听端口 (socket, bind, listen) 2. 查询 ...
- Android Socket通信详解
一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客 ...
- Android Socket 通信
Android socket 通信 安卓编写Socket客户端,实现连接Socket服务端通信. 创建Socket连接并获取服务端数据 先创建几个全局变量吧 private BufferedWrite ...
- 浅谈android Socket 通信及自建ServerSocket服务端常见问题
摘 要:TCP/IP通信协议是可靠的面向连接的网络协议,它在通信两端各建立一个Socket,从而在两端形成网络虚拟链路,进而应用程序可通过可以通过虚拟链路进行通信.Java对于基于TCP协议的网络通 ...
- Android Socket通信编程
安卓客户端通过socket与服务器端通讯一般可以按照以下几个步骤:(1).通过IP地址和端口实例化Socket,请求连接服务器:socket = new Socket(HOST, PORT); //h ...
随机推荐
- Java中String、StringBuilder以及StringBuffer
原文出处: 海子 相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String.StringBuilder和StringBuffe ...
- Flex疑难小杂症
本文主要解决Flex中一些小问题,收集一些小技巧(来自网络及个人经验) flex自动换行问题 有时候由于label .button等控件中需要用到text属性显示出文本,文本太长就涉及到换行问题,解 ...
- SharePoint迁移数据到生产环境
SharePoint迁移数据到生产环境步骤如下: 1. 安装部署好生产环境 2. 配置管理中心 3. 安装SPD工具 4. 备份数据库(放在数据库服务器) 5. 备份wsp包(部署在管理中心服务器) ...
- iOS开发之第三方登录QQ -- 史上最全最新第三方登录QQ方式实现
项目地址 : https://github.com/zhonggaorong/QQLoginDemo/tree/master 最新版本的qq登录实现步骤实现: 1. 首先,你需要去向腾讯申请账号. ...
- ios 面试题 经典(比较全) 根据重点总结
史上最全的iOS面试题及答案 1.写一个NSString类的实现 + (id)initWithCString:(c*****t char *)nullTerminatedCString encodin ...
- js,this,constrct ,prototype
这一章我们将会重点介绍JavaScript中几个重要的属性(this.constructor.prototype), 这些属性对于我们理解如何实现JavaScript中的类和继承起着至关重要的作 th ...
- python成长之路10——socketserver源码分析
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) 参数一:地址簇 socket.AF_INET ipv4(默认) socket.AF_INE ...
- NSString 用法大全。
一.NSString 创建字符串. NSString *astring = @"This is a String!"; 创建空字符串,给予赋值. NSString *astri ...
- ORA-00031: session marked for kill 标记要终止的会话
原文转载处:http://moonsoft.itpub.net/post/15182/203828 一些ORACLE中的进程被杀掉后,状态被置为"killed",但是锁定的资源很长 ...
- vs2010根据字符串内容添加断点
在vs中我们可以直接用表达式.数值型比较直接用操作符即可. 如i==2,i<2; 但是字符型比较呢? 加入我们有一个名为string的变量,定义如下: char *string="Tw ...