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

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,该博客是个好博客,作者也是个耿直的少年,只是实战方面略差一点;

2TCP客户端是个while无限循环接收的过程,该博客没有说明,有些不合理;

3TCP服务端应该是包含多个socket,主socket主要负责接收客户端来的连接,每接收一个socket就会创建一个新的与该socket通信,然后让他们自己玩自己的,这是客户端的简单描述,具体可参考该博客,笔者不做测试;

4TCP客户端接收数据要与服务端发送编码格式一致,比如都采用 utf-8,不然会乱码出现;

5,心态很重要,耐心很重要,最重要的是要相信解决了这个bug,还会有新的bug,所以急不得,参考笔者思路解决;

6,笔者记录此文,只是觉的在编码的路上,太寂寞了,太孤寂了;


—END


猜你喜欢

转载自blog.csdn.net/mapboo/article/details/77950354