android socket通信非阻塞式简单实现

关于网络通信就一句话:一切通信皆socket。socket分为阻塞和非阻塞,服务端多为阻塞式,客户端多为非阻塞式。

非阻塞式主要开了两个线程,一个线程(ReadThread)专门读取服务端返回,一个线程(WriteThread)专门读取往服务器写消息。这个类的代码如下:

//消息发送线程
    class SendThead extends Thread {
        String messag;

        //传入要发送的消息
        public void setMessag(String messag) {
            this.messag = messag;
        }


        @Override
        public void run() {
            while (true) {
                if (messag != null) {
                    System.out.println("发送内容为:" + messag);
                    try {
                        writer.write(messag);
                        writer.flush();
                        isSend = true;
                    } catch (IOException e) {
                        e.printStackTrace();
                        isSend = false;
                    } finally {
                        handler.sendEmptyMessage(404);
                        break;
                    }
                }
            }
        }
    }
  //消息读取线程
    class ReadThread extends Thread {
        @Override
        public void run() {
            while (true) {
                if (isSend) {
                    //如果发送成功才读取消息
                    try {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            builder.append(line + "\r\n");
                            reader.read();
                            isRead = true;
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        isRead = false;
                    } finally {
                        System.out.println("test 服务返回内容:" + builder.toString());
                        handler.sendEmptyMessage(200);
                        break;
                    }
                }
            }
        }
    }

以上两个类都在测试的activity中,下面是activity的主要代码

public class TestActivity extends AppCompatActivity {

    private EditText etInput;
    private TextView tvContent;
    private BufferedWriter writer;
    private BufferedReader reader;
    private SendThead sendThead;
    boolean isSend;//标记消息是否发送成功
    boolean isRead;//标记消息是否读取成功
    private Socket clientSocket;
    StringBuilder builder = new StringBuilder();
    private ReadThread readThread;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        etInput = ((EditText) findViewById(R.id.et_input));
        tvContent = ((TextView) findViewById(R.id.tv_content));
        //开启读写线程
        sendThead = new SendThead();
        sendThead.start();
        readThread = new ReadThread();
        readThread.start();
        //创建socket连接
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    clientSocket = new Socket(Constant.RTU_IP, Constant.RTU_PORT);
                    InputStream inputStream = clientSocket.getInputStream();
                    OutputStream outputStream = clientSocket.getOutputStream();
                    writer = new BufferedWriter(new OutputStreamWriter(outputStream));
                    reader = new BufferedReader(new InputStreamReader(inputStream));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 404:
                    ComUtils.showToast(TestActivity.this, isSend ? "发送成功" : "发送失败");
                    break;
                case 200:
                    String result = builder.toString();
                    tvContent.setText(isRead ? result : "读取失败");
                    break;
            }
        }
    };

    //点击按钮发送消息
    public void sendMessage(View view) throws InterruptedException {
        String input = etInput.getText().toString().trim();
        //如果连接成功就发送消息
        boolean alive = readThread.isAlive();
        System.out.println("线程是否开启:" + alive + "==");
        if (clientSocket.isConnected()) {
            sendThead.setMessag(input);
        } else {
            ComUtils.showToast(this, "请稍后发送,socket还在连接中");
            //也可以将消息存到未发送的消息集合中去
        }
    }

最后运行效果:
这里写图片描述

最后是关闭socket的方法:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (clientSocket != null && !clientSocket.isClosed()) {
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
             //那些读写的流不要去管,调用close方法,socket会去关闭读写流的,见下面google文档截图
             //Closing this socket will also close the socket's InputStream and OutputStream.
                clientSocket = null;
            }
        }
    }

这里写图片描述

anroid和硬件交互常常用到socket,由于原生socket写起来和用起来非常麻烦,目前封装比较好的socket通信框架是mina和netty,这两个框架的作者是同一个人,使用起来非常方便简化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值