您的位置:首页 > 移动开发 > Android开发

关于Android项目中Socket通信的那点事

2017-09-12 23:16 211 查看
Socket方面的知识点,相关的资料,如博客、视频、教程、官方文档等举不胜举,这里就不再赘述一遍了,只是笔者近日对项目中遇到的一点问题和思考做个总结,确切的来说,是对其中一篇博客的批注和补充吧,因为按照该博客的描述,会出现一些问题,笔者测试良久,或许写出来对一些朋友会有参考价值。

—前序

程序员,我们绝不重复造轮子,所以关于Socket,请看这位朋友的原创技术博客:Android:这是一份很详细的Socket使用攻略.
该博客详细描述了Socket的前世今生吧,非常感谢作者的无私奉献,是初学者非常好的技术资料,本人因项目需要TCP通信发送/接收数据,所以搜索一番就以该博客作为参考代码编写(搬运代码前,请一定要先读懂代码,切记切记);

—问题

客户端 -Android应用程序APP;
服务端 -PC上的一个TCP调试工具;

第一步,运行服务端工具,绑定端口即可;
第二步,运行APP,连接服务端,连接正常;
第三步,APP发送数据给服务端,正常接收;
第四步,服务端发送数据给APP,歇菜了,歇菜了...

—验证

既然问题出在了第四步,也是非常关键的功能点,必须破解才行,台阶如下:

思路一:自我怀疑
检查代码,检查代码,检查代码,重要的事说三遍,注意:该博客是点击获取服务端信息,这个不得不说,与现实是不符合的,至少笔者项目是连接成功后会持续接收服务端的发来的数据,用于刷新饼图、柱状图等信息,这里代码需要修改下,也就是加上无限循环while,必须如此;

思路二:三方验证
一番排斥,基本确定代码方面是没有问题,逻辑也是没有问题的,对没有初始化socket实例这种低级错误就不要犯了,于是乎下载了一个第三方的一个TCP调试APP,同样方式测试,第一步到第三步都没问题,第四步,居然服务端发来的这个调试APP收到了,收到了,收到了,那一刻,笔者的心是碎的,碎的,碎碎的;

思路三:断点调试
既然代码逻辑没有问题,三方验证已经毫无疑问的说明笔者代码是有问题的,开启Android的断点调试,吐槽下,断点调试比起iOS的来说,简直啰嗦,繁杂,报错乱七八糟,可能iOS的舒服让笔者有些鄙视Android吧,甚至比起VS的断点调试都差一截,不说了,Android也有优点,自己体会吧;
情况应该是这样的,while循环应该一直执行,断点发现,只执行一次,也就是while不重复循环,这怎么能持续呢,最后发现断点停在这句代码(博客157号代码):
 //
步骤3:通过输入流读取器对象 接收服务器发送过来的数据
                             
response = br.readLine();
初步推断线程卡住了,一直在读取,无法结束,导致while无法持续的工作,简单屏蔽可验证,也没有什么意义,问题应该找到了吧;

思路四:对比编码
先入为主,笔者一直用该博客的方式接收数据,当然了,其实也可以采用其他方式读取数据啊,于是乎,代码瞬间风格异变,进一步与本功能逻辑融合,几分钟后,APP接收到了服务器发来的问候,就这样,第四步也顺利解决了,可惜整个下午就这样过去了;

—代码

奉上相关修改后的代码供参考,有啥问题留言即可,笔者比较忙,谢谢,有问题参考如上思路请自行解决;
-更新UI
// 实例化主线程,用于更新接收过来的消息
mMainHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
mShowtext.setText(mShowtext.getText() + "--" + msg.obj.toString());
break;
}
}
};

-接收数据(注意 这里和参考博客是不一样的,仔细看吧)
/**
* 接收 服务器消息
*/

private void readMessage(){
// 利用线程池直接开启一个线程 & 执行该线程
mThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
while (true) {
if (socket != null){

// 步骤1:创建输入流对象InputStream
is = socket.getInputStream();

// 步骤2:创建输入流读取器对象 并传入输入流对象
InputStream inputStream = socket.getInputStream();
DataInputStream input = new DataInputStream(inputStream);

// 步骤3:接收服务器发送过来的数据
byte[] b = new byte[10000];
int length = input.read(b);
String Msg = new String(b, 0, length, "utf-8");

Log.i("TAGG","收到数据" + Msg);

// 步骤4:通知主线程,将接收的消息显示到界面
Message message = new Message();
message.what = 0;
message.obj = Msg;
mMainHandler.sendMessage(message);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}

—总结

1,该博客是个好博客,作者也是个耿直的少年,只是实战方面略差一点;
2,TCP客户端是个while无限循环接收的过程,该博客没有说明,有些不合理;
3,TCP服务端应该是包含多个socket,主socket主要负责接收客户端来的连接,每接收一个socket就会创建一个新的与该socket通信,然后让他们自己玩自己的,这是客户端的简单描述,具体可参考该博客,笔者不做测试;
4,TCP客户端接收数据要与服务端发送编码格式一致,比如都采用 utf-8,不然会乱码出现;
5,心态很重要,耐心很重要,最重要的是要相信解决了这个bug,还会有新的bug,所以急不得,参考笔者思路解决;
6,笔者记录此文,只是觉的在编码的路上,太寂寞了,太孤寂了;

—END

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: