当前位置: 移动技术网 > 移动技术>移动开发>Android > Android通过Socket与服务器之间进行通信的示例

Android通过Socket与服务器之间进行通信的示例

2019年07月30日  | 移动技术网移动技术  | 我要评论

一、首先进行server的编写:

public class socketserver {
 private static socket msocket;

 public static void main(string[] argc) {
  try {
   //1.创建一个服务器端socket,即serversocket,指定绑定的端口,并监听此端口
   serversocket serversocket = new serversocket(12345);
   inetaddress address = inetaddress.getlocalhost();
   string ip = address.gethostaddress();

   //2.调用accept()等待客户端连接
   system.out.println("~~~服务端已就绪,等待客户端接入~,服务端ip地址: " + ip);
   msocket = serversocket.accept();

   //3.连接后获取输入流,读取客户端信息
   inputstream is = null;
   inputstreamreader isr = null;
   bufferedreader br = null;
   outputstream os = null;
   is = msocket.getinputstream();
   isr = new inputstreamreader(is, "utf-8");
   br = new bufferedreader(isr);
   string info = null;
   while ((info = br.readline()) != null) {
    system.out.println("客户端发送过来的信息" + info);
    if (info.equals(backservice.heart_beat_string)) {
     sendmsg("ok");

    } else {
     sendmsg("服务器发送过来的信息" + info);

    }
   }

   msocket.shutdowninput();
   msocket.close();

  } catch (ioexception e) {
   e.printstacktrace();
  }

}


 //为连接上服务端的每个客户端发送信息
 public static void sendmsg(string msg) {
  printwriter pout = null;
  try {
   pout = new printwriter(new bufferedwriter(
    new outputstreamwriter(msocket.getoutputstream(), "utf-8")), true);
   pout.println(msg);
  } catch (ioexception e) {
   e.printstacktrace();
  }
 }
}

二、对客户端的编写,主要用用aidl进行server和client

aidl 的编写主要为以下三部分:

1、创建 aidl

1)、创建要操作的实体类,实现 parcelable 接口,以便序列化/反序列化
2)、新建 aidl 文件夹,在其中创建接口 aidl 文件以及实体类的映射 aidl 文件
3)、make project ,生成 binder 的 java 文件

2、服务端

1)、创建 service,在其中创建上面生成的 binder 对象实例,实现接口定义的方法
2)、在 onbind() 中返回

3、客户端

1)、实现 serviceconnection 接口,在其中拿到 aidl 类
2)、bindservice()
3)、调用 aidl 类中定义好的操作请求

ibackservice.aidl 文件

package com.example.dell.aidlservice;

// declare any non-default types here with import statements

interface ibackservice {
 /**
  * demonstrates some basic types that you can use as parameters
  * and return values in aidl.
  */

 boolean sendmessage(string message);
}

service的编写,命名为backservice

public class backservice extends service {
 private static final string tag = "danxx";
 public static final string heart_beat_string = "heartbeat";//心跳包内容
 /**
  * 心跳频率
  */
 private static final long heart_beat_rate = 3 * 1000;
 /**
  * 服务器ip地址
  */
 public static final string host = "172.16.50.115";
 /**
  * 服务器端口号
  */
 public static final int port = 12345;
 /**
  * 服务器消息回复广播
  */
 public static final string message_action = "message_action";
 /**
  * 服务器心跳回复广播
  */
 public static final string heart_beat_action = "heart_beat_action";
 /**
  * 读线程
  */
 private readthread mreadthread;

 private localbroadcastmanager mlocalbroadcastmanager;
 /***/
 private weakreference<socket> msocket;

 // for heart beat
 private handler mhandler = new handler();
 /**
  * 心跳任务,不断重复调用自己
  */
 private runnable heartbeatrunnable = new runnable() {

  @override
  public void run() {
   if (system.currenttimemillis() - sendtime >= heart_beat_rate) {
    boolean issuccess = sendmsg(heart_beat_string);//就发送一个\r\n过去 如果发送失败,就重新初始化一个socket
    if (!issuccess) {
     mhandler.removecallbacks(heartbeatrunnable);
     mreadthread.release();
     releaselastsocket(msocket);
     new initsocketthread().start();
    }
   }
   mhandler.postdelayed(this, heart_beat_rate);
  }
 };

 private long sendtime = 0l;
 /**
  * aidl通讯回调
  */
 private ibackservice.stub ibackservice = new ibackservice.stub() {

  /**
   * 收到内容发送消息
   * @param message 需要发送到服务器的消息
   * @return
   * @throws remoteexception
   */
  @override
  public boolean sendmessage(string message) throws remoteexception {
   return sendmsg(message);
  }
 };

 @override
 public ibinder onbind(intent arg0) {
  return ibackservice;
 }

 @override
 public void oncreate() {
  super.oncreate();
  new initsocketthread().start();
  mlocalbroadcastmanager = localbroadcastmanager.getinstance(this);
 }

 public boolean sendmsg(final string msg) {
  if (null == msocket || null == msocket.get()) {
   return false;
  }
  final socket soc = msocket.get();
  if (!soc.isclosed() && !soc.isoutputshutdown()) {
   new thread(new runnable() {
    @override
    public void run() {
     try {
      outputstream os = soc.getoutputstream();
      string message = msg + "\r\n";
      os.write(message.getbytes());
      os.flush();
     } catch (ioexception e) {
      e.printstacktrace();
     }
    }
   }).start();
   sendtime = system.currenttimemillis();//每次发送成数据,就改一下最后成功发送的时间,节省心跳间隔时间
  } else {
   return false;
  }
  return true;
 }

 private void initsocket() {//初始化socket
  try {
   //1.创建客户端socket,指定服务器地址和端口
   socket so = new socket(host, port);
   msocket = new weakreference<socket>(so);
   mreadthread = new readthread(so);
   mreadthread.start();
   mhandler.postdelayed(heartbeatrunnable, heart_beat_rate);//初始化成功后,就准备发送心跳包
  } catch (unknownhostexception e) {
   e.printstacktrace();
  } catch (ioexception e) {
   e.printstacktrace();
  }
 }

 /**
  * 心跳机制判断出socket已经断开后,就销毁连接方便重新创建连接
  *
  * @param msocket
  */
 private void releaselastsocket(weakreference<socket> msocket) {
  try {
   if (null != msocket) {
    socket sk = msocket.get();
    if (!sk.isclosed()) {
     sk.close();
    }
    sk = null;
    msocket = null;
   }
  } catch (ioexception e) {
   e.printstacktrace();
  }
 }

 class initsocketthread extends thread {
  @override
  public void run() {
   super.run();
   initsocket();
  }
 }

 // thread to read content from socket
 class readthread extends thread {
  private weakreference<socket> mweaksocket;
  private boolean isstart = true;

  public readthread(socket socket) {
   mweaksocket = new weakreference<socket>(socket);
  }

  public void release() {
   isstart = false;
   releaselastsocket(mweaksocket);
  }

  @override
  public void run() {
   super.run();
   socket socket = mweaksocket.get();
   if (null != socket) {
    try {
     inputstream is = socket.getinputstream();
     byte[] buffer = new byte[1024 * 4];
     int length = 0;
     while (!socket.isclosed() && !socket.isinputshutdown() && isstart && ((length = is.read(buffer)) != -1)) {
      if (length > 0) {
       string message = new string(arrays.copyof(buffer, length)).trim();
       log.e(tag, message);
       //收到服务器过来的消息,就通过broadcast发送出去
       if (message.equals("ok")) {//处理心跳回复
        intent intent = new intent(heart_beat_action);
        mlocalbroadcastmanager.sendbroadcast(intent);

       } else {
        //其他消息回复
        intent intent = new intent(message_action);
        intent.putextra("message", message);
        mlocalbroadcastmanager.sendbroadcast(intent);
       }
      }
     }
    } catch (ioexception e) {
     e.printstacktrace();
    }
   }
  }
 }

 @override
 public void ondestroy() {
  super.ondestroy();
  mhandler.removecallbacks(heartbeatrunnable);
  mreadthread.release();
  releaselastsocket(msocket);
 }

}

mainactivity

public class mainactivity extends appcompatactivity implements view.onclicklistener {
 private textview mresulttext;
 private edittext medittext;
 private intent mserviceintent;

 private ibackservice ibackservice;

 private serviceconnection conn = new serviceconnection() {

  @override
  public void onservicedisconnected(componentname name) {
   ibackservice = null;

  }

  @override
  public void onserviceconnected(componentname name, ibinder service) {
   ibackservice = ibackservice.stub.asinterface(service);
  }
 };

 class messagebackreciver extends broadcastreceiver {
  private weakreference<textview> textview;

  public messagebackreciver(textview tv) {
   textview = new weakreference<textview>(tv);
  }

  @override
  public void onreceive(context context, intent intent) {
   string action = intent.getaction();
   textview tv = textview.get();
   if (action.equals(backservice.heart_beat_action)) {
    if (null != tv) {
     log.i("danxx", "get a heart heat");
     tv.settext("get a heart heat");
    }
   } else {
    log.i("danxx", "get a heart heat");
    string message = intent.getstringextra("message");
    tv.settext("服务器消息:" + message);
   }
  }
 }

 private messagebackreciver mreciver;

 private intentfilter mintentfilter;

 private localbroadcastmanager mlocalbroadcastmanager;

 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);

  mlocalbroadcastmanager = localbroadcastmanager.getinstance(this);

  mresulttext = (textview) findviewbyid(r.id.resule_text);
  medittext = (edittext) findviewbyid(r.id.content_edit);
  findviewbyid(r.id.send).setonclicklistener(this);
  findviewbyid(r.id.send1).setonclicklistener(this);
  mreciver = new messagebackreciver(mresulttext);

  mserviceintent = new intent(this, backservice.class);

  mintentfilter = new intentfilter();
  mintentfilter.addaction(backservice.heart_beat_action);
  mintentfilter.addaction(backservice.message_action);

 }

 @override
 protected void onstart() {
  super.onstart();
  mlocalbroadcastmanager.registerreceiver(mreciver, mintentfilter);
  bindservice(mserviceintent, conn, bind_auto_create);
 }

 @override
 protected void onstop() {
  super.onstop();
  unbindservice(conn);
  mlocalbroadcastmanager.unregisterreceiver(mreciver);
 }

 public void onclick(view view) {
  switch (view.getid()) {
   case r.id.send:
    string content = medittext.gettext().tostring();
    try {
     boolean issend = ibackservice.sendmessage(content);//send content by socket
     toast.maketext(this, issend ? "success" : "fail", toast.length_short).show();
     medittext.settext("");
    } catch (remoteexception e) {
     e.printstacktrace();
    }
    break;

   case r.id.send1:
    new thread(new runnable() {
     @override
     public void run() {
      try {
       acceptserver();
      } catch (ioexception e) {
       e.printstacktrace();
      }
     }
    }).start();
    break;

   default:
    break;
  }
 }


 private void acceptserver() throws ioexception {
  //1.创建客户端socket,指定服务器地址和端口
  socket socket = new socket("172.16.50.115", 12345);
  //2.获取输出流,向服务器端发送信息
  outputstream os = socket.getoutputstream();
  printwriter printwriter = new printwriter(os); //将输出流包装为打印流

  //获取客户端的ip地址
  inetaddress address = inetaddress.getlocalhost();
  string ip = address.gethostaddress();
  printwriter.write("客户端:~" + ip + "~ 接入服务器!!");
  printwriter.flush();
  socket.shutdowninput();
  socket.close();
 }
}

源码地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网