Socket多线程接发指令

基础知识

  • 多线程
  • 消息机制
  • 基于TCP协议的网络通信

创建多线程的方法

  1. 一种是,继承Thread类
    Thread类代表线程类,它的两个最主要的方法是:
    run()——包含线程运行时所执行的代码
    Start()——用于启动线程
  2. 另一种是,实现Runnable接口
    实现Runnable接口,让类实现Runnable接口,然后把run方法单独提出来

两种方法的区别:
这里写图片描述

  1. Callable、Future和FutureTask:在执行完线程之后可以返回执行结果
    原文链接:http://www.cnblogs.com/dolphin0520/p/3949310.html

handle消息机制

Handler类的主要作用:

  • 在新启动的线程中发送消息 handler.sendMessage(msg);
  • 在主线程中获取、处理消息 public void handleMessage(Message msg)
  • 消息的载体Message

基于TCP协议的网络通信

SmartBed上位机控制APP指令传送与接收采用TCP的sokect多线程


/**
 * Description:指令传送和接收的线程
 * @author zhangjing
 *
 */
public class SBClientThread implements Runnable
{
    private Context context;
    private String IPAddress;
    private int ServerPort;
    private boolean isRemoterServer;
    private Socket s;
    // 定义向UI线程发送消息的Handler对象
    private Handler handler;
    // 定义接收UI线程的消息的Handler对象
    public Handler revHandler;
    // 该线程所处理的Socket所对应的输入流
    InputStream is = null;
    // 该线程所处理的Socket所对应的输出流
    OutputStream os = null;

    /**
     * 设备连接构造函数
     * @param context
     * @param handler
     * @param iPString IP地址
     * @param portString 端口号
     */
    public SBClientThread(Context context, Handler handler,String iPString, String portString)
    {
        this.context = context;
        this.handler = handler;
        IPAddress = iPString;
        ServerPort = Integer.parseInt(portString);  
        isRemoterServer = false;
    }
    /**
     * 远程服务器连接构造函数
     * @param context
     * @param handler
     */
    public SBClientThread(Context context, Handler handler){
        this.context = context;
        this.handler = handler;
        IPAddress = "xxxx.xxxx.xxxx.xxxx";//远程服务器2
        ServerPort = 8383;  
        isRemoterServer = true;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try
        {

            //Thread.sleep(1000);//线程暂停一秒
            s = new Socket();
            SocketAddress endpoint = new InetSocketAddress(IPAddress , ServerPort); 
            //设置连接超时时间
            s.connect(endpoint, 5*1000);
            //s = new Socket(IPAddress,ServerPoset);
            is = s.getInputStream();
            os = s.getOutputStream();
            //输出连接信息
            if(s.isConnected()){
                SBCommand.isConnect = true;
                Message msg = new Message();
                msg.what = 0x567;
                //msg.obj = new String(s+"已连接!");
                if(isRemoterServer){
                    //msg.obj = new String("远程服务器连接成功 !\n\t\t\t\t\t [ "+s.getInetAddress().getHostAddress()+":"+s.getPort()+" ]");
                    msg.obj = new String("远程服务器连接成功 !");
                }else {
                    msg.obj = new String("设备连接成功 !\n\t\t\t\t\t [ "+s.getInetAddress().getHostAddress()+":"+s.getPort()+" ]");
                }

                handler.sendMessage(msg);
                //提示
                handler.post(new Runnable() { 
                    @Override 
                    public void run() { 
                        if(isRemoterServer){
                            Toast.makeText(context.getApplicationContext(),"远程服务器连接成功",
                                    Toast.LENGTH_SHORT).show();
                        }else {
                            Toast.makeText(context.getApplicationContext(),"设备连接成功",
                            Toast.LENGTH_SHORT).show();
                        }

                    } 
                }); 
            }
            // 启动一条子线程来读取服务器响应的数据
            new Thread()
            {
                @Override
                public void run()
                {
                    try
                    {

                        // 每当读到来自服务器的数据之后,发送消息通知程序界面处理该数据
                        while(true){

                            int count = 0;  
                            while (count == 0) {  
                                count = is.available();
                            }  
                            byte[] buffer = new byte[count];  
                            is.read(buffer); 
                            String revString = SBCommand.bytesToHexString(buffer);
                            //revString =" " + revString;
                            Message msg = new Message();
                            msg.what = 0x123;
                            msg.obj = revString;
                            handler.sendMessage(msg);
                        }
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                    }

                }
            }.start();
            // 为当前线程初始化Looper
            Looper.prepare();
            // 创建revHandler对象
            revHandler = new Handler()
            {
                @Override
                public void handleMessage(Message msg)
                {
                    // 接收到UI线程中用户输入的数据
                    if (msg.what == 0x345)
                    {
                        // 将用户在文本框内输入的内容写入网络
                        // 接收到UI线程中用户输入的数据
                        try
                        {
                            String commString = null;
                            commString = msg.obj.toString();
                            os.write(SBCommand.hexStringToByte(commString));
                            os.flush();
                        }
                        catch (Exception e)
                        {
                            e.printStackTrace();

                            Message msg1 = new Message();
                            msg1.what = 0x789;
                            msg1.obj = new String("连接已断开!");
                            handler.sendMessage(msg1);
                            handler.post(new Runnable() { 
                                @Override 
                                public void run() { 
                                    Toast.makeText(context.getApplicationContext(),"指令发送失败,请重新连接",
                                            Toast.LENGTH_LONG).show();
                                } 
                            });
                        }
                    }
                }

            };
            // 启动Looper
            Looper.loop();  
        }
        catch(SocketTimeoutException ex)
        {
            Message msg = new Message();
            msg.what = 0x789;
            msg.obj = new String("连接超时!");
            handler.sendMessage(msg);
            //SBClient.isConnect = false; 放在handler消息队列中 ,以下同理
            //提示
            handler.post(new Runnable() { 
                @Override 
                public void run() { 
                    Toast.makeText(context,"请检查连接信息,重新连接",
                            Toast.LENGTH_SHORT).show();
                }
            });
        }
        catch (Exception e)
        {
            e.printStackTrace();
            Message msg = new Message();
            msg.what = 0x789;
            msg.obj = new String("连接失败!");
            handler.sendMessage(msg);
            //SBClient.isConnect = false;
            handler.post(new Runnable() { 
                @Override 
                public void run() { 
                    Toast.makeText(context.getApplicationContext(),"请检查连接信息,重新连接",
                            Toast.LENGTH_SHORT).show();
                }
            }); 
        }
    }
    /**
     * 注销Soket,关闭wifi
     */
    public void onDestroy() {
        //此程序影响UI线程,故增加新线程
        new Thread(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {       
                    if(s!=null)
                    {
                        s.close();
                        s = null;
                        is.close();
                        is = null;
                        os.close();
                        os = null;
                        SBCommand.isConnect = false;
                        ProgressDialog.closeDialogProgress();
                        Message msg = new Message();
                        msg.what = 0x567;
                        msg.obj = new String("连接关闭成功!");
                        //注意:Toast在线程中需要消息机制
                        handler.sendMessage(msg);
                        //提示
                        handler.post(new Runnable() { 
                            @Override 
                            public void run() { 
                                Toast.makeText(context.getApplicationContext(),"设备连接关闭成功",
                                        Toast.LENGTH_SHORT).show();
                            }
                        }); 
                    }
                }
                catch (IOException e) {
                e.printStackTrace();
                }
            }
        }.start();
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章