• 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();
    

    完成!哈哈哈,刺激!

  • 相关阅读:
    简单的进度条程序
    python装饰器
    冒泡,递归
    实现随机验证码
    三木运算,三元运算
    set()集合
    list()列表
    python3.5 Str类型与bytes类型转换
    说说编码与转义的区别
    Java 中字符编码相关的问题解析
  • 原文地址:https://www.cnblogs.com/wjw1014/p/11804296.html
Copyright © 2020-2023  润新知