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 BufferedWriter(new OutputStreamWriter( socket.getOutputStream())); InputStream inputStream = socket.getInputStream(); DataInputStream input = new DataInputStream(inputStream); // 创建一个字节数组用来接收服务端发来的字节流,多大自己说了算 byte[] b = new byte[100000]; // 写一个死循环,不停的接收服务端发来的数据 while (true) { // 将数据读入字节数组,返回长度 int length = input.read(b); // 如果服务端没发数据就return不在往下执行,继续读数据 if (length <= 0) return; // 如果服务端发的数据不为空,则把字节数组转成字符串 msg = new String(b, 0, length, "gb2312"); // 后边就可以调用数据解析的方法 .... }

一般的通讯格式都是Json的,查一下把json格式的字符串转换成json对象然后根据key值获取value的代码:

// 其中,data是json格式的字符串,转换成了jsonObject对象 JSONObject jsonObject = new JSONObject(data); // 获取jsonObject对象的device_id值,当然device_id是String类型的,如果是int就用int String i = jsonObject.getString("device_id");

发送数据给服务端

发送数据给服务端的前提是已经完成了Socket连接

// 首先判断一下socket是不是已经创建连接了,如果没有就不管它 if (socket == null) return; // str是准备发给服务端的字符串 writer.write(str); // 发出去(留坑,继续看完) writer.flush();

这就完成了Android编写Socket与服务端通信的功能。但是这个Socket IPV4的地址可以,IPV6的地址我没试过,听说好像有点问题,但是大部分都用IPV4,如果真的用到IPV6的话,再百度!

纠错

问题来咯!!! 我遇到的大坑! 在很早之前我开发的时候上面的操作编写方式完全没问题! 但是,昨天我写的时候发现会报错!报错在 writer.flush() 这个地方。 百度之后发现: 老版的android不会有问题,但是新版本的android(好像是sdk10以上)已经不允许在UI线程(主线程)中发起网络请求了,会抛出NetWorkInUIThreadException。 所以说给服务端发送数据的时候需要写到子线程里。

new Thread(new Runnable() { @Override public void run() { // 首先判断一下socket是不是已经创建连接了,如果没有就不管它 if (socket == null) return; // str是准备发给服务端的字符串 writer.write("我是Android客户端发的数据"); // 发出去 writer.flush(); } }).start();

这样就开一个子线程,在子线程中编写发送数据的代码或调用发送数据的方法就没问题了!

留坑!

生命不息,留坑不止!! 如果我们把发送数据的代码封装成一个方法,并且发送的数据需要方法传参,比如:

public void sendData(String str){ new Thread(new Runnable() { @Override public void run() { // 首先判断一下socket是不是已经创建连接了,如果没有就不管它 if (socket == null) return; // str是准备发给服务端的字符串,会报错,传进来的参数子线程进不来 writer.write(str); // 发出去 writer.flush(); } }).start(); }

发现父线程传进的参数,子线程读不到,我郁闷了好久,自己写了个内部类解决了。

/** * 接口类,实现主线程向子线程传值 */ class sendData implements Runnable { String str; public sendValueToServer(String str) { this.str = str; } @Override public void run() { try { // 如果socket连接失败,则停止执行 if (socket == null) return; // 发送传进来的值 writer.write(str); // 发出去 writer.flush(); } catch (IOException e) { e.printStackTrace(); } } }

然后在需要发送的地方写:

new Thread(new sendData ("传值数据")).start();

完成!哈哈哈,刺激!

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )