安卓之必须了解的实时通信(Socket)

安卓之必须了解的实时通信(Socket),第1张

概述Socket: 有服务器和客户端之分,其是对TCP/IP的封装,使用IP地址加端口,确定一个唯一的点。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket

Socket:

有服务器和客户端之分,其是对TCP/IP的封装,使用IP地址加端口,确定一个唯一的点。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。值得注意的是用户使用的端口最好大于1024,因为小于1024的大部分端口都是被系统占用的。此章将实现安卓socket客户端编程。

 

安卓的线程基本机制

一个程序就是一个进程,一个进程里可以有多个线程,每个进程必须有一个主线程。对应安卓一个应用程序就是一个进程,其主线程就是平常所说的安卓主UI线程。安卓实现多线程编程,其有一个重要的原则就是更新UI必须在主线程,但耗时 *** 作必须在子线程中,如果耗时 *** 作在主线程编写(如网络访问)当阻塞时间达到一定时,应用就会强制退出,那网络访问就面临着一个不可避免的问题:子线程更新UI *** 作如何实现。

 

Handler

Handler主要用于异步消息的处理: 有点类似辅助类,封装了消息投递、消息处理等接口。当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息进行处理,也就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的 *** 作。

 

Message

Handler接收与处理的消息对象,其中消息类型有

public int arg1和public int arg2:存放简单的整数类型消息

public Object obj:发送给接收器的任意对象,不管是整数,字符串,某个类对象均可

public int what:用户自定义的消息代码,这样接受者可以了解这个消息的信息,每个handler各自包含自己的消息代码,所以不用担心自定义的消息跟其他handlers有冲突。

 

 安卓端实现效果

在同一网络下的一个设备开启一个端口的监听,做为socket服务器,并获取到服务器设备的IP地址和端口号,将其格式化为 “IP:端口” 进行输入,如 “193.169.44.198:8081”,点击连接即可。安卓作为socket客户端与服务器交互数据。

 

编程实现

获取网络访问权限:

实现socket编程,必须开启网络访问权限

<uses-permission androID:name="androID.permission.INTERNET" />

 

编写Handler消息处理类:

handler消息处理类是MainActivity类的内部类,当消息队列不为空时将自动进入,获取到消息值并分析其中内容

 1 private Handler mainhandler=new Handler(){ 2     @OverrIDe 3     public voID handleMessage(Message msg) { 4         //获取到命令,进行命令分支 5         int handi=msg.arg1; 6         switch (handi){ 7             case 0: 8                 String ormsg=(String)msg.obj; 9                 disSocket();断开网络10                 Toast.makeText(MainActivity.this,"发生错误=>:"+ormsg,Toast.LENGTH_SHORT).show();11                 break;12             case 113                 Toast.makeText(MainActivity.,1)">14                 15             case 216                 收到数据17                 String str1=18                 main_rx.setText(str1);19                 20             default:21         }22     }23 };

 

连接按钮监听:

当连接按钮按下时,将会立即获取输入框的内容并进行字符串分隔,得到IP地址和端口号,开启线程进行网络连接 

连接按钮监听 2 main_conn.setonClickListener( VIEw.OnClickListener() { 3       @OverrIDe 4        onClick(VIEw v) { 5           String strip=main_ip.getText().toString().trim(); 6           if(strip.indexOf(":")>=0){ 7               8               开始启动连接线程 9                Socket_thread(strip).start();10 11           }12 13       }14 });

 

发送数据按钮监听:

当发送数据按钮按下时,将会立即获取到发送输入框的内容,分别可以调用字符串发送函数和十六进制发送函数进行数据发送

发送按钮监听 2 main_send.setonClickListener( @OverrIDe 4   5    得到输入框内容 6    final String senddata=main_tx.getText().toString().trim(); 7  8         if(!senddata.equals("")){ 9             发送因为使用的是线程,所以先后顺序不一定10             发送字符串数据            sendStrSocket(senddata);发送十六进制数据13             sendByteSocket(new byte[]{0x01,0x02,0x03});14 15            }else Toast.makeText(MainActivity.16             }17 });

 

开始网络连接线程:

该类为MainActivity类的内部类,实现线程连接socket服务器,并获取输入输出流,并开启接收线程

class Socket_thread extends Thread{private String IP="";ip地址 4     private int PORT=0;端口号 5     public Socket_thread(String strip){构造方法需要传递服务器的IP地址和端口号 7         如: 192.168.43.222:8099进行字符串分隔,得到服务器IP地址和端口号 9         String[] stripx= strip.split(":");10         this.IP=stripx[0];11         this.PORT=Integer.parseInt(stripx[1]);12 14      run() {15         try {16 17             disSocket();断开上次连接18             if(sock !=null19                 outx.close();20                 inx.close();21                 sock.close();关闭22                 sock=23 24             开始连接服务器,此处会一直处于阻塞,直到连接成功25             sock=new Socket(this.IP,this.PORT);26 27             阻塞停止,表示连接成功,发送连接成功消息28             Message message= Message();29             message.arg1=130             mainhandler.sendMessage(message);31 32          }catch (Exception e) {33             Message message=34             message.arg1=035             message.obj="连接服务器时异常"36 37 38             System.out.println("建立失败////////////////////////////////////////////"39             e.printstacktrace();40             return41 42         43             获取到输入输出流44             outx=sock.getoutputStream();45             inx=sock.getinputStream();46         } 47             发送连接失败异常48             Message message=49             message.arg1=050             message.obj="获取输入输出流异常"51 52 53             System.out.println("流获取失败////////////////////////////////////////////"54 55             56 57 58         new Outx().start();59          Inx().start();60 61 }

 

关闭socket函数:

关闭socket之前将先关闭输入输出流,这样才能更加安全的关闭socket 

 disSocket(){ 2     如果不为空,则断开socket 5             outx.close(); 6             inx.close(); 7             sock.close(); 8             sock =  9         } (Exception e){11             Message message=12             message.arg1=013             message.obj="断开连接时发生错误"14 15 17 18 19 }

  

数据接收线程实现: 

接收线程将实现数据的接收,并把接收到的数据通过消息发送给处理类,特别注意的是 inx.read(bu) 返回如果是 -1 则表示服务器断开了连接或者其它非主动调用关闭socket方法断开造成的错误

循环接收数据class Inx  Thread{        @OverrIDewhile(true 6 byte[] bu=byte[1024 9            得到-1表示服务器断开10           int conut=inx.read(bu);设备重启,异常 将会一直停留在这11             if(conut==-112                 13                 Message message=14                 message.arg1=015                 message.obj="服务器断开"                mainhandler.sendMessage(message);17                 disSocket();断开连接18                 System.out.println("**********服务器异常*********:"+conut);21 22           必须去掉前后空字符,不然有这个会有1024个字符每次23           strread=new String(bu,"GBK").trim();24           发送出收到的数据25           Message message=26           message.arg1=227           message.obj=strread;28           mainhandler.sendMessage(message);29 30           }  (IOException e) {31               System.out.println(e);32 33            }34  } }}

 

发送字符串函数: 

网络编程的最终发送的内容是字节,所以发送字符串需要通过getBytes进行编码

发送字符串voID sendStrSocket(final String senddata){new Thread( Runnable() { 4  6        7          可以经过编码发送字符串 8          outx.write(senddata.getBytes("gbk"));"utf-8" 9 10       } 11          12          Message message=13          message.arg1=014          message.obj="数据发送异常"15          mainhandler.sendMessage(message);   }).start();19 }

 

发送十六进制函数:

通过字节数组,可以实现多个十六进制数据的发送

发送十六进制 2  voID sendByteSocket(final byte[] senddata){ 5        6         8             outx.write(senddata);10         } 12              Message message=13              message.arg1=014              message.obj="数据发送异常"             mainhandler.sendMessage(message);    }).start();19 }

  

 参考:

https://blog.csdn.net/rabbit_in_androID/article/details/50585156

https://www.imooc.com/article/25134?block_ID=tuijian_wz

总结

以上是内存溢出为你收集整理的安卓之必须了解的实时通信(Socket)全部内容,希望文章能够帮你解决安卓之必须了解的实时通信(Socket)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1121208.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存