欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-04-12 11:43:24
一、首先进行server的编写: public class socketserver { private static socket msocket;...

一、首先进行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();
 }
}

源码地址

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