zoukankan      html  css  js  c++  java
  • 23-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 加入消息处理

    https://www.cnblogs.com/yangfengwu/p/11203546.html

    先做接收消息

     

     

     然后接着

     

     

    public class MainActivity extends AppCompatActivity {
    
        EditText editTextActivityMain1,editTextActivityMain2;//定义两个EditText变量,变量名字我一般设置的和先前页面里面的一样
        Button buttonActivityMain1;//连接按钮
    
        Socket socket;//定义一个Socket
        MyHandler myHandler;
        private OutputStream outputStream;//TCP发送数据使用
        private InputStream inputStream;//TCP接收数据使用
    
        byte[] TcpReceiveData = new byte[1024];//用来缓存接收的数据
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            myHandler = new MyHandler();
            //获取控件
            editTextActivityMain1 = findViewById(R.id.editTextActivityMain1);
            editTextActivityMain2 = findViewById(R.id.editTextActivityMain2);
            buttonActivityMain1 = findViewById(R.id.buttonActivityMain1);
            buttonActivityMain1.setText("连接");//加上这个,否则按钮需要点击两次才会判断按钮的Text是"连接"
    
            //连接按钮点击事件
            buttonActivityMain1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (buttonActivityMain1.getText().toString() == "连接"){
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                //这里面写具体的程序
                                try {
                                    socket = new Socket(editTextActivityMain1.getText().toString(),Integer.valueOf(editTextActivityMain2.getText().toString()));//连接TCP服务器
                                    if (socket.isConnected()){//如果连接上TCP服务器
                                        Log.e("MainActivity", "isConnected");
                                        Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                        msg.what = 1;//设置消息变量的 what 变量值 为1
                                        myHandler.sendMessage(msg);//插入消息队列
    
                                        outputStream = socket.getOutputStream();//获取输出数据流
                                        inputStream = socket.getInputStream();//获取输入数据流
                                        TcpClientReceive();//加载接收函数
                                    }
                                }
                                catch (Exception e){
                                    Log.e("MainActivity", e.toString());
                                }
                            }
                        }).start();
                    }
                    else {
                        try{ socket.close(); }catch (Exception e){} //关闭连接
                        try{ inputStream.close(); }catch (Exception e){} //关闭数据流
                        buttonActivityMain1.setText("连接");//按钮显示连接
                    }
                }
            });
        }
    
        //TCP客户端接收数据
        public void TcpClientReceive(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while(socket.isConnected()){//如果客户端一直连接着就一直在任务里面
                        try{
                            int TcpReceiveDataLen = inputStream.read(TcpReceiveData);//接收数据,服务器断开会返回-1
    
                            if(TcpReceiveDataLen!=-1){
                                byte[] Buffer = new byte[TcpReceiveDataLen];//创建一个新的数组
                                System.arraycopy(TcpReceiveData, 0, Buffer, 0, TcpReceiveDataLen);//拷贝数据
                                Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                msg.what = 2;//设置消息变量
                                msg.obj = Buffer;//obj 可以接收任意类型的变量
                                myHandler.sendMessage(msg);//插入消息队列
                            }
                            else{//断开了连接
                                Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                msg.what = 9;//设置消息变量
                                myHandler.sendMessage(msg);//插入消息队列
                            }
                        }catch (Exception e){//接收数据有错误
                            Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                            msg.what = 9;//设置消息变量
                            myHandler.sendMessage(msg);//插入消息队列
                        }
                    }
                }
            }).start();
        }
    
    
    
        //Handler
        class MyHandler extends Handler {
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 1){//接收到消息变量的 what 变量值 为1
                    buttonActivityMain1.setText("断开");//按钮显示断开
                }
                else if (msg.what == 2){//接收到消息变量的 what 变量值 为2
                    try{
                        byte[] TcpReadData = (byte[])msg.obj;//接收消息
                        Log.e("MainActivity", new String(TcpReadData) );//打印消息
                    }catch (Exception e){}
    
                }
                else if (msg.what == 9){//接收到消息变量的 what 变量值 为9
                    try{ socket.close(); }catch (Exception e){} //关闭连接
                    try{ inputStream.close(); }catch (Exception e){} //关闭连接
                    buttonActivityMain1.setText("连接");//按钮显示连接
                }
            }
        }
    }

    测试Android 接收数据

     测试服务器突然故障

     

    稍等,,我还是直接打印一下日志比较好

     

     ................有BUG

     加上break;

    再测试

    public class MainActivity extends AppCompatActivity {
    
        EditText editTextActivityMain1,editTextActivityMain2;//定义两个EditText变量,变量名字我一般设置的和先前页面里面的一样
        Button buttonActivityMain1;//连接按钮
    
        Socket socket;//定义一个Socket
        MyHandler myHandler;
        private OutputStream outputStream;//TCP发送数据使用
        private InputStream inputStream;//TCP接收数据使用
    
        byte[] TcpReceiveData = new byte[1024];//用来缓存接收的数据
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            myHandler = new MyHandler();
            //获取控件
            editTextActivityMain1 = findViewById(R.id.editTextActivityMain1);
            editTextActivityMain2 = findViewById(R.id.editTextActivityMain2);
            buttonActivityMain1 = findViewById(R.id.buttonActivityMain1);
            buttonActivityMain1.setText("连接");//加上这个,否则按钮需要点击两次才会判断按钮的Text是"连接"
    
            //连接按钮点击事件
            buttonActivityMain1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (buttonActivityMain1.getText().toString() == "连接"){
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                //这里面写具体的程序
                                try {
                                    socket = new Socket(editTextActivityMain1.getText().toString(),Integer.valueOf(editTextActivityMain2.getText().toString()));//连接TCP服务器
                                    if (socket.isConnected()){//如果连接上TCP服务器
                                        Log.e("MainActivity", "isConnected");
                                        Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                        msg.what = 1;//设置消息变量的 what 变量值 为1
                                        myHandler.sendMessage(msg);//插入消息队列
    
                                        outputStream = socket.getOutputStream();//获取输出数据流
                                        inputStream = socket.getInputStream();//获取输入数据流
                                        TcpClientReceive();//加载接收函数
                                    }
                                }
                                catch (Exception e){
                                    Log.e("MainActivity", e.toString());
                                }
                            }
                        }).start();
                    }
                    else {
                        try{ socket.close(); }catch (Exception e){} //关闭连接
                        try{ inputStream.close(); }catch (Exception e){} //关闭数据流
                        buttonActivityMain1.setText("连接");//按钮显示连接
                    }
                }
            });
        }
    
        //TCP客户端接收数据
        public void TcpClientReceive(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while(socket.isConnected()){//如果客户端一直连接着就一直在任务里面
                        try{
                            int TcpReceiveDataLen = inputStream.read(TcpReceiveData);//接收数据,服务器断开会返回-1
    
                            if(TcpReceiveDataLen!=-1){
                                byte[] Buffer = new byte[TcpReceiveDataLen];//创建一个新的数组
                                System.arraycopy(TcpReceiveData, 0, Buffer, 0, TcpReceiveDataLen);//拷贝数据
                                Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                msg.what = 2;//设置消息变量
                                msg.obj = Buffer;//obj 可以接收任意类型的变量
                                myHandler.sendMessage(msg);//插入消息队列
                            }
                            else{//断开了连接
                                Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                msg.what = 9;//设置消息变量
                                myHandler.sendMessage(msg);//插入消息队列
                                break;
                            }
                        }catch (Exception e){//接收数据有错误
                            Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                            msg.what = 9;//设置消息变量
                            myHandler.sendMessage(msg);//插入消息队列
                            break;
                        }
                    }
                }
            }).start();
        }
    
    
    
        //Handler
        class MyHandler extends Handler {
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 1){//接收到消息变量的 what 变量值 为1
                    buttonActivityMain1.setText("断开");//按钮显示断开
                }
                else if (msg.what == 2){//接收到消息变量的 what 变量值 为2
                    try{
                        byte[] TcpReadData = (byte[])msg.obj;//接收消息
                        Log.e("MainActivity", new String(TcpReadData) );//打印消息
                    }catch (Exception e){}
    
                }
                else if (msg.what == 9){//接收到消息变量的 what 变量值 为9
                    try{ socket.close(); }catch (Exception e){} //关闭连接
                    try{ inputStream.close(); }catch (Exception e){} //关闭连接
                    buttonActivityMain1.setText("连接");//按钮显示连接
                    Log.e("MainActivity", "和服务器断开连接!!!" );//打印消息
                }
            }
        }
    }

    现在做一下发送和接收数据的页面

     点击这个,改为百分比

     

    拖到50%

    我更改了背景色,和显示字体的颜色

     

     

    现在把接收的数据显示出来

     

     测试

     

    现在做一个显示16进制和字符串切换的

     

     其实咱接收过来的就是16进制,咱需要把16进制转化为16进制字符串

    /**
         * 16进制byte转16进制String--用空格隔开
         * @param bytes
         * @return
         */
        public static String byteToHexStr(byte[] bytes)
        {    
            String str_msg = "";
            for (int i = 0; i < bytes.length; i++){    
                str_msg = str_msg + String.format("%02X",bytes[i])+" ";
            }    
            return str_msg;    
        }  

     测试

        

     

     不过看一下,在这个位置显示的...咱修改下

     

     

     首先说一点

     发送数据都是给个数组

    所以

     

     

     添加上格式

    实际上咱获取的文本框里面的都是字符串

    咱需要把字符串转化为    列如: "33"   ==>  0x33

    /** 
         * 将已十六进制编码后的字符串src,以每两个字符分割转换为16进制形式 如:"2B44EFD9" --> byte[]{0x2B, 0x44, 0xEF, 
         * 0xD9} 
         * 
         * @param src 
         *            String 
         * @return byte[] 
         */ 
        public static byte[] HexString2Bytes(String str) { 
            StringBuilder sb = null;
            String src = null;
            if ((str.length()%2)!=0) {//数据不是偶数
                sb = new StringBuilder(str);//构造一个StringBuilder对象
                sb.insert(str.length()-1, "0");//在指定的位置1,插入指定的字符串
                src = sb.toString();
            }
            else {
                src = str;
            }
            Log.e("error", "str.length()"+str.length());
            byte[] ret = new byte[src.length() / 2]; 
            byte[] tmp = src.getBytes(); 
            for (int i = 0; i < tmp.length / 2; i++) 
            { 
                ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]); 
            } 
            return ret; 
        } 
        
        
        /** 
         * 将两个ASCII字符合成一个字节; 如:"EF"--> 0xEF 
         * 
         * @param src0 
         *            byte 
         * @param src1 
         *            byte 
         * @return byte 
         */ 
        public static byte uniteBytes(byte src0, byte src1) { 
            try 
            {
                byte _b0 = Byte.decode("0x"+new String(new byte[] { src0 })) .byteValue(); 
                _b0 = (byte) (_b0 << 4); 
                byte _b1 = Byte.decode("0x"+new String(new byte[] { src1 })) .byteValue(); 
                byte ret = (byte) (_b0 ^ _b1); 
                return ret; 
            } catch (Exception e) {
                // TODO: handle exception
            }
            return 0;
        } 

     

    public class MainActivity extends AppCompatActivity {
    
        EditText editTextActivityMain1,editTextActivityMain2,editTextActivityMain3;//IP,端口号,发送数据框
        Button buttonActivityMain1,buttonActivityMain2,buttonActivityMain3;//连接按钮,发送,清除接收
        TextView textViewActivityMain4;//接收文本
        CheckBox checkBoxActivityMain1,checkBoxActivityMain2;//切换显示,发送格式选择
    
        Socket socket;//定义一个Socket
        MyHandler myHandler;
        private OutputStream outputStream;//TCP发送数据使用
        private InputStream inputStream;//TCP接收数据使用
        byte[] TcpReceiveData = new byte[1024];//用来缓存接收的数据
        byte[] TcpSendData = new byte[1024];//用来缓存发送的数据
        int TcpSendDataLen =0;//发送的数据个数
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            myHandler = new MyHandler();
            //获取控件
            editTextActivityMain1 = findViewById(R.id.editTextActivityMain1);//IP
            editTextActivityMain2 = findViewById(R.id.editTextActivityMain2);//端口号
            editTextActivityMain3 = findViewById(R.id.editTextActivityMain3);//发送数据框
            buttonActivityMain1 = findViewById(R.id.buttonActivityMain1);//连接按钮
            buttonActivityMain2 = findViewById(R.id.buttonActivityMain2);//发送数据
            buttonActivityMain3 = findViewById(R.id.buttonActivityMain3);//清除接收
            textViewActivityMain4 = findViewById(R.id.textViewActivityMain4);//接收数据文本
            checkBoxActivityMain1 = findViewById(R.id.checkBoxActivityMain1);//切换显示
            checkBoxActivityMain2 = findViewById(R.id.checkBoxActivityMain2);//发送格式选择
    
            buttonActivityMain1.setText("连接");//加上这个,否则按钮需要点击两次才会判断按钮的Text是"连接"
    
            //连接按钮点击事件
            buttonActivityMain1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (buttonActivityMain1.getText().toString() == "连接"){
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                //这里面写具体的程序
                                try {
                                    socket = new Socket(editTextActivityMain1.getText().toString(),Integer.valueOf(editTextActivityMain2.getText().toString()));//连接TCP服务器
                                    if (socket.isConnected()){//如果连接上TCP服务器
                                        Log.e("MainActivity", "isConnected");
                                        Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                        msg.what = 1;//设置消息变量的 what 变量值 为1
                                        myHandler.sendMessage(msg);//插入消息队列
    
                                        outputStream = socket.getOutputStream();//获取输出数据流
                                        inputStream = socket.getInputStream();//获取输入数据流
                                        TcpClientReceive();//加载接收函数
                                    }
                                }
                                catch (Exception e){
                                    Log.e("MainActivity", e.toString());
                                }
                            }
                        }).start();
                    }
                    else {
                        try{ socket.close(); }catch (Exception e){} //关闭连接
                        try{ inputStream.close(); }catch (Exception e){} //关闭数据流
                        buttonActivityMain1.setText("连接");//按钮显示连接
                    }
                }
            });
    
            //发送按钮
            buttonActivityMain2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    try{
                        //获取发送数据框里面的数据
                        if (checkBoxActivityMain2.isChecked()){//16进制发送
                            byte[] TcpSendData1 = HexString2Bytes(editTextActivityMain3.getText().toString().replace(" ", ""));
                            TcpSendDataLen = TcpSendData1.length;
                            TcpSendData = TcpSendData1;
                        }
                        else{
                            byte[] TcpSendData2 = editTextActivityMain3.getText().toString().replace(" ", "").getBytes("utf-8");//"gb2312","gbk","us-ascii"
                            TcpSendDataLen = TcpSendData2.length;
                            TcpSendData = TcpSendData2;
                        }
                        if (socket!=null && socket.isConnected()){//如果TCP是正常连接的
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    try{
                                        outputStream.write(TcpSendData,0,TcpSendDataLen);//发送数据
                                    }catch (Exception e){}
                                }
                            }).start();
                        }
                    }catch (Exception  e){}
                }
            });
        }
    
        //TCP客户端接收数据
        public void TcpClientReceive(){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while(socket.isConnected()){//如果客户端一直连接着就一直在任务里面
                        try{
                            int TcpReceiveDataLen = inputStream.read(TcpReceiveData);//接收数据,服务器断开会返回-1
    
                            if(TcpReceiveDataLen!=-1){
                                byte[] Buffer = new byte[TcpReceiveDataLen];//创建一个新的数组
                                System.arraycopy(TcpReceiveData, 0, Buffer, 0, TcpReceiveDataLen);//拷贝数据
                                Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                msg.what = 2;//设置消息变量
                                msg.obj = Buffer;//obj 可以接收任意类型的变量
                                myHandler.sendMessage(msg);//插入消息队列
                            }
                            else{//断开了连接
                                Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                                msg.what = 9;//设置消息变量
                                myHandler.sendMessage(msg);//插入消息队列
                                break;
                            }
                        }catch (Exception e){//接收数据有错误
                            Message msg = myHandler.obtainMessage();//从消息队列拉取个消息变量
                            msg.what = 9;//设置消息变量
                            myHandler.sendMessage(msg);//插入消息队列
                            break;
                        }
                    }
                }
            }).start();
        }
    
    
    
        //Handler
        class MyHandler extends Handler {
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 1){//接收到消息变量的 what 变量值 为1
                    buttonActivityMain1.setText("断开");//按钮显示断开
                }
                else if (msg.what == 2){//接收到消息变量的 what 变量值 为2
                    try{
                        byte[] TcpReadData = (byte[])msg.obj;//接收消息
                        if (checkBoxActivityMain1.isChecked()){//选择了显示16进制
                            textViewActivityMain4.append(byteToHexStr(TcpReadData));
                        }
                        else {
                            textViewActivityMain4.append(new String(TcpReadData,"utf-8"));//追加显示数据 "utf-8","gb2312","gbk","us-ascii"  参见:https://www.cnblogs.com/yangfengwu/p/10274289.html
                        }
                        //textViewActivityMain4.setText(new String(TcpReadData));//显示一次数据重新刷新显示
                        Log.e("MainActivity", new String(TcpReadData) );//打印消息
                    }catch (Exception e){}
    
                }
                else if (msg.what == 9){//接收到消息变量的 what 变量值 为9
                    try{ socket.close(); }catch (Exception e){} //关闭连接
                    try{ inputStream.close(); }catch (Exception e){} //关闭连接
                    buttonActivityMain1.setText("连接");//按钮显示连接
                    Log.e("MainActivity", "和服务器断开连接!!!" );//打印消息
                }
            }
        }
    
    
        /**
         * 16进制byte转16进制String--用空格隔开
         * @param bytes
         * @return
         */
        public static String byteToHexStr(byte[] bytes)
        {
            String str_msg = "";
            for (int i = 0; i < bytes.length; i++){
                str_msg = str_msg + String.format("%02X",bytes[i])+" ";
            }
            return str_msg;
        }
    
    
        /**
         * 将已十六进制编码后的字符串src,以每两个字符分割转换为16进制形式 如:"2B44EFD9" --> byte[]{0x2B, 0x44, 0xEF,
         * 0xD9}
         *
         * @param src
         *            String
         * @return byte[]
         */
        public static byte[] HexString2Bytes(String str) {
            StringBuilder sb = null;
            String src = null;
            if ((str.length()%2)!=0) {//数据不是偶数
                sb = new StringBuilder(str);//构造一个StringBuilder对象
                sb.insert(str.length()-1, "0");//在指定的位置1,插入指定的字符串
                src = sb.toString();
            }
            else {
                src = str;
            }
            Log.e("error", "str.length()"+str.length());
            byte[] ret = new byte[src.length() / 2];
            byte[] tmp = src.getBytes();
            for (int i = 0; i < tmp.length / 2; i++)
            {
                ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
            }
            return ret;
        }
    
    
        /**
         * 将两个ASCII字符合成一个字节; 如:"EF"--> 0xEF
         *
         * @param src0
         *            byte
         * @param src1
         *            byte
         * @return byte
         */
        public static byte uniteBytes(byte src0, byte src1) {
            try
            {
                byte _b0 = Byte.decode("0x"+new String(new byte[] { src0 })) .byteValue();
                _b0 = (byte) (_b0 << 4);
                byte _b1 = Byte.decode("0x"+new String(new byte[] { src1 })) .byteValue();
                byte ret = (byte) (_b0 ^ _b1);
                return ret;
            } catch (Exception e) {
                // TODO: handle exception
            }
            return 0;
        }
    }

    测试

     

     

     

  • 相关阅读:
    从头搭建Openstack运行环境(七)--实现负载均衡与外网访问
    ML2分层端口绑定技术在SDN开发中的应用(一)
    从头搭建Openstack运行环境(六)--租户网络间路由与防火墙
    翻译校对1
    pykube-pod.obj的json字符串解析
    第一版k8s
    the server does not allow access to the requested resource
    have fun of Docker
    Clean Development Series
    Understanding the GitHub Flow官方的是最好的,永远要看第一手资料
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/11204436.html
Copyright © 2011-2022 走看看