android tcp非阻塞,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还在连接中");

//也可以将消息存到未发送的消息集合中去

}

}

最后运行效果:

0818b9ca8b590ca3270a3433284dd417.png

最后是关闭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;

}

}

}

0818b9ca8b590ca3270a3433284dd417.png

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值