android开发-基于tcp连接的,两部android设备之间的交流通信 - Go语言中文社区

android开发-基于tcp连接的,两部android设备之间的交流通信


最近在项目开发中,需要用到一台android设备去控制另一台android设备的显示。

第一次尝试的做法是使用组播的方式,由一台主控设备发消息给受控设备。

但是,由于组播发送消息的模式是发送一个数据包,也就是udp。

了解过一点网络方面知识的人都知道,udp传输是不可靠的,数据包发过去了,接不接收得到是不管的,

所以这样的做法导致,虽然数据包发过去了,但是不能每次都能成功接收到。但是项目必须是每次发都能接收到数据的,所以不采用组播的方式。

最后选择使用TCP连接的方式来做,这种方式就是可靠的。

具体的udp,tcp的知识,有需要了解的就在网上查找吧,这里就不做解释了。


一、首先先上图

1、控制端,无连接状态


打开控制端的界面是这样显示的,因为只是个例子,所以请自动忽略美观吧。大笑


2、再来张无连接状态的受控端图


但是这个无连接状态是在没有打开控制端的时候才这样显示的,当控制端先打开的时候,受控端界面是这样的


然后控制端界面立即显示


当看到两端的界面如上图所示,则代表两端已经连接,这时候就可以开始操作发送数据了。


二、接下来就让控制端发个消息给受控端

     其实发消息很简单,只需要点击一下控制端界面中的  “发送数据给客户端” 即可,

     然后受控端就能接收到消息

    

这样受控端就成功收到消息了,这时候受控端可以根据收到的数据进行显示了,

例子就是这么简单粗暴。


三、好像还缺少了点什么?

  看到这里应该会发出    “我勒个去,没代码说个毛线啊!!!”。


  第一次写文章,先包涵着看嘛。

  代码来了:

1、控制端

首先,tcp连接是需要设备的ip的,所以先贴出查设备ip的代码先

/***
     * 使用WIFI时,获取本机IP地址
     *
     * @param mContext
     * @return
     */
    private static String getWIFILocalIpAddress(Context mContext) {

        //获取wifi服务
        WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
        //判断wifi是否开启
        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
        }
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        String ip = formatIpAddress(ipAddress);
        return ip;
    }

    private static String formatIpAddress(int ipAdress) {

        return (ipAdress & 0xFF) + "." +
                ((ipAdress >> 8) & 0xFF) + "." +
                ((ipAdress >> 16) & 0xFF) + "." +
                (ipAdress >> 24 & 0xFF);
    }

这代码也是网上看到的,具体在哪篇文章看到的忘记了,如果作者看到这篇文章后需要我写明出处的,请联系我,我好贴出来,包涵啊。

当然,读取ip是需要手机权限的,我就把这个小项目需要用到的权限先贴出来了,也不多,就几个

    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.INTERNET"/>
好了,先获取到ip,接下来有用。


那么监听tcp的连接请求:

try {
            Boolean endFlag = false;
            ServerSocket ss = new ServerSocket(8800);
            while (!endFlag) {
                // 等待客户端连接
                Socket s = ss.accept();
                addIPToList(s);
                //读取客户端发来的消息
                BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
                String message = input.readLine();
                Log.e("来自客户端的消息 : ", message);
                //向客户端发送消息
                //注意第二个参数据为true将会自动flush,否则需要需要手动操作output.flush()
                mOutput = new PrintWriter(s.getOutputStream(), true);
                mOutput.println("已连接到服务器!!!");
            }
            ss.close();

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
当然,记得这段代码需要放在子线程中运行。


发送消息:

if (ips != null && ips.size() > 0) {
            for (int i = 0; i < ips.size(); i++) {
                try {
                    Socket next = ips.get(i);
                    PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(next.getOutputStream(),"UTF-8")),true);
                    out.println(s);
                    out.flush();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
到这里,你可能发现了一个 ips 的变量了吧,这个是一个存放受控端Socket的集合,Socket就是从连接请求代码中的  addIPToList(s)  方法中添加进去的,

既然是个集合,你应该想到这也可以发送给多个受控端吧,也就是可以控制多个设备的意思了。


2、受控端

请求连接的代码:

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    mS = new Socket(ip, 8800);
                    // outgoing stream redirect to socket
                    OutputStream out = mS.getOutputStream();
                    // 注意第二个参数据为true将会自动flush,否则需要需要手动操作out.flush()
                    mOutput = new PrintWriter(out, true);
                    mOutput.println("Hello IdeasAndroid!");
                    mInput = new BufferedReader(new InputStreamReader(mS
                            .getInputStream(),"UTF-8"));

                    String mMessage;
                    while (true) {
                        try {
                            if ((mMessage = mInput.readLine()) != null) {
                                String decode = URLDecoder.decode(mMessage, "UTF-8");
                                //这里加“-”是为了避免得到的字符串前面有多了奇怪的字符,测试中有遇到过,加“-”完再截取让得到的字符串准确
                                if (decode.contains("{") && decode.contains("}")){
                                    decode = "-"+decode+"-";
                                    int i = decode.indexOf("{");
                                    int j = decode.lastIndexOf("}");
                                    decode = decode.substring(i, j+1);
                                }

                                Message message1 = Message.obtain();
                                message1.obj = decode;
                                mHandler.sendMessage(message1);
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
看到上面的ip变量了吧,这个就是上面说需要用到的控制端ip了。

中间那段对字符串的判断,由于发送的是java对象的json字符串,如果不是json字符串,也同样可以收到。


显示收到的信息:

private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.e("接收到字符串  === ", (String) msg.obj);
            String beanString = (String) msg.obj;
            if (beanString.contains("{")){
                mGson = new Gson();
                Bean bean = mGson.fromJson(beanString, Bean.class);
                mTvShow.setText("名字 = "+bean.getName()+"n"+"时间 : "+bean.getTime());
            }else {
                mTvShow.setText(beanString);
            }

        }
    };



好了,基本上关键代码都贴出来了。

因为是第一次写,写的不好。好想很多都将详细,但是好像那样太啰嗦了点。
















版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xqx5140/article/details/52787871
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-08 10:52:31
  • 阅读 ( 994 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢