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

声明:

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

时间: 2025-01-05 00:45:30

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

Java中Socket通信的知识回顾---学习笔记

两台计算机进行通信的基本前提: (1)IP地址: 每台计算机都有自己独一无二的IP地址,根据IP地址判断与哪台计算机进行通信. (2)端口号: 每个应用程序都有自己专属的端口,根据端口号判断与计算机中的哪个应用程序进行通信. 说明: <1>用于区分不同应用程序 <2>端口号的范围:0-65535,其中0-1023是为系统保留的端口号 <3>常用的协议的端口号: http:80 ftp:21 telnet:23 <4>IP地址+端口号=Socket,Socke

java NIO socket 通信实例

java Nio 通信与Bio通信主要不同点: 1.Nio中的单个channel即可支持读操作也可以支持写操作,而bio中读操作要用inputstream,写操作要outputstream. 2.nio 采用byteBuffer 作为内存缓存区,向channel里写或者度操作,bio基本是用byte[] 3.nio采用 selector组件轮询读取就绪channel 服务端demo代码: package com.my.socket3; import java.io.ByteArrayOutput

Android Socket 通信

Android socket 通信 安卓编写Socket客户端,实现连接Socket服务端通信. 创建Socket连接并获取服务端数据 先创建几个全局变量吧 private BufferedWriter writer = null; Socket socket; 创建Socket // 填好IPV4的IP地址和端口,服务端会提供,问服务端要 socket = new Socket("192.168.1.156", 1234); // 下面三句照抄就行 writer = new Buff

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

摘  要:TCP/IP通信协议是可靠的面向连接的网络协议,它在通信两端各建立一个Socket,从而在两端形成网络虚拟链路,进而应用程序可通过可以通过虚拟链路进行通信.Java对于基于TCP协议的网络通信提供了良好的封装,使用Socket对象代表两端的通信接口,通过Socket产生I/O流进行网络通信. 自建ServerSocket服务端时可能因PC与手机平板终端未接入同一路由器,因此无法访问服本地IP,可以尝试以下两种方式解决 关键词: Socket; ServerSocket;本地IP; ad

C++服务器与java进行socket通信案例

分类: [java]2012-10-08 12:03 14539人阅读 评论(46) 收藏 举报 注:本代码版权所有!!!转载时请声明源地址:http://blog.csdn.net/nuptboyzhb/article/details/8047619 你可以学习,分享,修改,教学等.但是不得用于商业目的.目前已经发现互联网上大量与本文完全相同的文章,但是却把作者信息删除的干干净净,并且据为己有,打上某培训机构的广告!实属可恶! 最新消息:项目成品连接:http://blog.csdn.net/

Java:Socket通信

Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求.ServerSocket用于服务器端,Socket是建立网络连接时使用的.在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话.对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别.套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认. 实例一:

Socket通信——C++server端和Javaclient

一句话来说就是.C++和Java 通过socket进行通信.传输数据.通过发送"字节流"就可以. 字节对于C++和java来说是通用的.可是传输的过程有很多问题须要注意,我为了弄清楚这个过程,查了一些资料,做了一些整理. 不了解C++ socket编程,能够看这篇博客: Linux 下:socket通信(Linux下,C/C++语言):http://blog.csdn.net/giantpoplar/article/details/47657303 Windows下:winsock:h

java的Socket通信例子及关于java.net.SocketException: Socket is closed错误

今天写socket数据相互通信的时候,碰到一个及其蛋疼的错误.单向传输数据的时候server与client是没有问题的,但是两个都有输入输出操作的时候就出现了这个问题 java.net.SocketException: Socket is closed: 下面附代码: Server: StringBuffer result = new StringBuffer(""); int port = 9090; //定义一个ServerSocket监听在端口9090上 ServerSocket

java利用socket通信模拟实现ARQ停止等待协议

---恢复内容开始--- 1//服务端,发送方 1 //客户端,接收方 2 3 import java.awt.*; 4 import java.io.*; 5 import java.net.*; 6 import java.util.*; 7 import javax.swing.*; 8 9 public class IClient extends JFrame { 10 JPanel jp = new JPanel(); 11 JTextArea jta = new JTextArea(