android客户端指什么意思,Android-TCP客户端的实现

前言

因为需求,可能需要在安卓上完成一个同时包含UDP和TCP的项目。因此,本来做iOS的小编在闲暇之余,研究了一波安卓的TCP客户端是如何实现的。

UDP客户端实现请点这里:UDP。

实现

小编看了很多资料,发现网上的资料大多数很复杂,并不能满足小编最基础的需求。因此,小编决定自己封装一个简易的类来方便使用。

创建单例

首先,小编想到的是单例。因为不管是iOS还是安卓,都应该有单例。单例的好处主要在于可以使该类在系统内存中只存在一个对象,可以节约系统资源,对于一些需要频繁创建和销毁的对象,可以明显的提高系统的性能。

安卓的单例写法有很多种,最后小编选择了一种自己认为比较好的写法,如下:

public class TaskCenter {

private static TaskCenter instance;

// 构造函数私有化

private TaskCenter() {

super();

}

// 提供一个全局的静态方法

public static TaskCenter sharedCenter() {

if (instance == null) {

synchronized (TaskCenter.class) {

if (instance == null) {

instance = new TaskCenter();

}

}

}

return instance;

}

建立线程

为了能更好的处理数据,小编在这里建立了一个线程,在TCP连接时启动。如下:

private static final String TAG = "TaskCenter";

// Socket

private Socket socket;

// IP地址

private String ipAddress;

// 端口号

private int port;

// 线程

private Thread thread;

// Socket输出流

private OutputStream outputStream;

// Socket输入流

private InputStream inputStream;

-------------------------------------------------------------------

/**

* 通过IP地址(域名)和端口进行连接

*

* @param ipAddress IP地址(域名)

* @param port 端口

*/

public void connect(final String ipAddress, final int port) {

thread = new Thread(new Runnable() {

@Override

public void run() {

try {

socket = new Socket(ipAddress, port);

// socket.setSoTimeout ( 2 * 1000 );//设置超时时间

if (isConnected()) {

TaskCenter.sharedCenter().ipAddress = ipAddress;

TaskCenter.sharedCenter().port = port;

if (connectedCallback != null) {

connectedCallback.callback();

}

outputStream = socket.getOutputStream();

inputStream = socket.getInputStream();

receive();

Log.i(TAG,"连接成功");

}else {

Log.i(TAG,"连接失败");

if (disconnectedCallback != null) {

disconnectedCallback.callback(new IOException("连接失败"));

}

}

} catch (IOException e) {

e.printStackTrace();

Log.e(TAG,"连接异常");

if (disconnectedCallback != null) {

disconnectedCallback.callback(e);

}

}

}

});

thread.start();

}

TCP发送和接收的集成

集成的思路是开启线程,建立一个方法去初始化socket,初始化完后,并在线程中加入接收数据的方法。如下:

/**

* 接收数据

*/

public void receive() {

while (isConnected()) {

try {

/**得到的是16进制数,需要进行解析*/

byte[] bt = new byte[1024];

// 获取接收到的字节和字节数

int length = inputStream.read(bt);

// 获取正确的字节

byte[] bs = new byte[length];

System.arraycopy(bt, 0, bs, 0, length);

String str = new String(bs, "UTF-8");

if (str != null) {

if (receivedCallback != null) {

receivedCallback.callback(str);

}

}

Log.i(TAG,"接收成功");

} catch (IOException e) {

Log.i(TAG,"接收失败");

}

}

}

/**

* 发送数据

*

* @param data 数据

*/

public void send(final byte[] data) {

new Thread(new Runnable() {

@Override

public void run() {

if (socket != null) {

try {

outputStream.write(data);

outputStream.flush();

Log.i(TAG,"发送成功");

} catch (IOException e) {

e.printStackTrace();

Log.i(TAG,"发送失败");

}

} else {

connect();

}

}

}).start();

}

在接收到数据包之后需要将数据回调出去,但是网上大多数都是把控制器在类中,这不是小编的初衷。因此小编用了一种类似iOS中Block的方式去回调。如下:

// 连接回调

private OnServerConnectedCallbackBlock connectedCallback;

// 断开连接回调(连接失败)

private OnServerDisconnectedCallbackBlock disconnectedCallback;

// 接收信息回调

private OnReceiveCallbackBlock receivedCallback;

-------------------------------------------------------------------

/**

* 回调声明

*/

public interface OnServerConnectedCallbackBlock {

void callback();

}

public interface OnServerDisconnectedCallbackBlock {

void callback(IOException e);

}

public interface OnReceiveCallbackBlock {

void callback(String receicedMessage);

}

public void setConnectedCallback(OnServerConnectedCallbackBlock connectedCallback) {

this.connectedCallback = connectedCallback;

}

public void setDisconnectedCallback(OnServerDisconnectedCallbackBlock disconnectedCallback) {

this.disconnectedCallback = disconnectedCallback;

}

public void setReceivedCallback(OnReceiveCallbackBlock receivedCallback) {

this.receivedCallback = receivedCallback;

}

/**

* 移除回调

*/

private void removeCallback() {

connectedCallback = null;

disconnectedCallback = null;

receivedCallback = null;

}

既然有开启TCP,那肯定有关闭TCP的时候,关闭TCO时需要接收信息的回调和线程也移除。注意:在接收包时,有可能因为socket原因而接收失败,此时也需要关闭。这里并不影响下次发送,因为下次发送时会判断socket存不存在,不存在会重新建立。如下:

/**

* 断开连接

*/

public void disconnect() {

if (isConnected()) {

try {

if (outputStream != null) {

outputStream.close();

}

socket.close();

if (socket.isClosed()) {

if (disconnectedCallback != null) {

disconnectedCallback.callback(new IOException("断开连接"));

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

到这里,就集成完成了。

3.使用

使用起来相当简单,导入类,初始化,通过该类的方法发送信息和接收信息即可,如下:

TaskCenter.sharedCenter().setDisconnectedCallback(new TaskCenter.OnServerDisconnectedCallbackBlock() {

@Override

public void callback(IOException e) {

textView_receive.setText(textView_receive.getText().toString() + "断开连接" + "\n");

}

});

TaskCenter.sharedCenter().setConnectedCallback(new TaskCenter.OnServerConnectedCallbackBlock() {

@Override

public void callback() {

textView_receive.setText(textView_receive.getText().toString() + "连接成功" + "\n");

}

});

TaskCenter.sharedCenter().setReceivedCallback(new TaskCenter.OnReceiveCallbackBlock() {

@Override

public void callback(String receicedMessage) {

textView_receive.setText(textView_receive.getText().toString() + receicedMessage + "\n");

}

});

-----------------------------------------------------------------------

//连接

TaskCenter.sharedCenter().connect("xxx.xxx.xx.xxxx",xxxx);

//发送

TaskCenter.sharedCenter().send(msg.getBytes());

断开连接

TaskCenter.sharedCenter().disconnect();

到这里为止,TCP客户端的Demo就完成了,写的不好的地方欢迎大家指出,Demo下载地址:Demo。最后,希望这篇文章对各位看官们有所帮助。对支持小编的看官们表示感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值