基于Tcp协议的Socket的简单封装
近期公司买了新的Android板子作用在自助借还机上,该设备内部集成了若干个天线,采用tcp协议与Android主板进行通讯,因此需要对socket的应用做一个简单的封装。
简单了解一下Socket
1、首先shocket不是一种协议,而是一个程序调用的接口API,属于传输层。
2、通过使用Socket,可以在Android中应用TCP/IP协议。
3、用户只需要调用Socket去整理数据、组织数据来达到符合指定的协议,就可以达到通讯。
Android建立Socket连接过程
1、创建一个Socket实例
2、系统为该Socket实例分配一个未被使用的本地端口号
3、操作系统创建一个含本地、远程地址、端口号的套接字数据结构(系统将一直保存该数据结构直到这个连接关闭)
4、在创建Socket实例的构造器正确返回之前,完成TCP的三次握手。
5、TCP握手完成后,Socket实例化完成。
开始实施
public class SocketClient {
private static SocketClient socketClient ;
public ReentrantLock reentrantLock = new ReentrantLock();
private Socket mClient;
private ReadConnectListener readConnectListener;
private Thread mConnectThread;
private OutputStream outputStream;
public Socket getmClient() {
return mClient;
}
public void setmClient(Socket mClient) {
this.mClient = mClient;
}
/**
* 天线信息数据返回的接口回调
*/
public interface ReadConnectListener {
public void onReceiveData(String data);
}
/**
* 读写器数据监听器
*
* @param readConnectListener
*/
public void setOnReadConnectListener(ReadConnectListener readConnectListener) {
this.readConnectListener = readConnectListener;
}
/**
* 创建单例
*
* @return
*/
public static SocketClient getInstance() {
if (socketClient == null) {
socketClient = new SocketClient ();
}
return socketClient;
}
@SuppressLint("HandlerLeak")
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 100:
if (readConnectListener != null) {
readConnectListener.onReceiveData(msg.getData().getString("data"));
}
break;
}
}
};
/**
* 进行连接
* 创建Socket对象 并且接收指定服务端的IP及端口号
* @param IP
* @param Port
*/
public void createConnect(final String IP, final int Port) {
if (mConnectThread == null) {
mConnectThread = new Thread(new Runnable() {
@Override
public void run() {
connect(IP, Port);
}
});
mConnectThread.start();
}
}
/**
* 创建连接
* @param ip
* @param port
* @throws IOException
*/
public void connect(String ip, int port) {
if (mClient == null) {
try {
mClient = new Socket(ip, port);
mClient.setSoTimeout(6000);
} catch (IOException e) {
Log.d("TCP", e.toString());
}
setmClient(mClient);
}
}
/*
* 发送消息
*/
public void sendMessage(byte[] data) {
//因为要保证读取每条天线上的货品状态,所以要进行短的周期内不断的轮询
//添加一个同步锁,保证数据的一发一收
reentrantLock.lock();
try {
outputStream = mClient.getOutputStream();
outputStream.write(data);
Log.d(">>>>>发送请求====", StringUtil.byte2HexStr(data));
outputStream.flush();
InputStream finalInputStream = mClient.getInputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = finalInputStream.read(buffer)) != -1) {
byte[] dataBuf = StringUtil.subBytes(buffer, 0, len);
String datas = StringUtil.byte2HexStr(dataBuf);
Log.d("接收消息", datas);
Message message = new Message(); //创建Message
message.what = 100; //设置参数
Bundle bundle = new Bundle();
Log.d(">>>>>接收回复====", datas);
bundle.putString("data", datas);
message.setData(bundle);
//将消息发送到主线程
mHandler.sendMessage(message);
reentrantLock.unlock();
break;
}
} catch (Exception e) {
Log.d("e===", e.toString());
}
}
/**
* 关闭连接
*/
public void closeConnect() {
if (mClient != null) {
try {
mClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}