最近在做一些Socket通讯的项目,用一些简单的Socket又不稳定,所以 利用这个机会自己封了一套Socket通讯的实现方法.,实现的过程非常简单.经过测试,使用起来还算稳定.换不多说 直接上代码.
// 首先是几个回调,用于Socket转态和数据的回调
public interface ConnectListener {
void receive(byte[] data);
void disconnect();
void connectOk();
void connectFailed(Exception e);
}
//设置Socket的一些配置信息
public class SessionConfig {
/** address */
private String ip;
/** port */
private int port;
/** connect timeout, unit seconds */
private int timeOut;
/** connect Interval, unit seconds */
private int interval;
/** get address */
public String getIp() {
return ip;
}
/** get port */
public int getPort() {
return port;
}
/** get connect timeout */
public int getTimeOut() {
return timeOut;
}
/** get connect Interval */
public int getInterval() {
return interval;
}
public static class Builder {
/** address */
private String ip;
/** port */
private int port;
/** connect timeout, unit seconds */
private int timeOut;
/** connect Interval, unit seconds */
private int interval;
/** set address */
public Builder setIp(String ip) {
this.ip = ip;
return this;
}
/** set port */
public Builder setPort(int port) {
this.port = port;
return this;
}
/** set connect timeout */
public Builder setTimeOut(int timeOut) {
this.timeOut = timeOut;
return this;
}
/** set connect Interval */
public Builder setInterval(int interval) {
this.interval = interval;
return this;
}
/** build a SessionConfig */
public SessionConfig build() {
SessionConfig config = new SessionConfig();
config.ip = this.ip;
config.port = this.port;
config.timeOut = this.timeOut;
config.interval = this.interval;
return config;
}
}
@Override
public String toString() {
return "SessionConfig [ip=" + ip + ", port=" + port + ", timeOut="
+ timeOut + ", interval=" + interval + "]";
}
//socket的连接,读取数据的线程,代码非常简单,也有一些注释 看一下就会明白
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
abstract class SocketTransceiver implements Runnable {
private static final String TAG = "SocketTransceiver";
private boolean runFlag;
private Socket socket;
private InetAddress addr;
private InputStream inputStream;
private OutputStream outputStream;
SocketTransceiver(Socket socket) {
this.socket = socket;
this.addr = socket.getInetAddress();
}
InetAddress getInetAddress() {
return addr;
}
void start() {
runFlag = true;
try {
inputStream = this.socket.getInputStream();
outputStream = this.socket.getOutputStream();
} catch (IOException e) {
runFlag = false;
}
new Thread(this, TAG).start();
}
void stop() {
runFlag = false;
try {
socket.shutdownInput();
inputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (runFlag) {
try {
if (inputStream == null) return;
byte[] buffer = new byte[inputStream.available()];
int len = inputStream.read(buffer);
if(len > 5) {
receive(addr, buffer);
// if (msgCheck(buffer)) {
// bytesOperation(buffer, len);
// }
}
Thread.sleep(20);
} catch (Exception e) {
runFlag = false;
disconnect(addr);
}
}
}
/**
* 处理粘包、半包、断包的情况
* @param buffer read buffer
* @param len data length
*/
/*private void bytesOperation(byte[] buffer, int len) {
byte[] data = new byte[len];
System.arraycopy(buffer, 0, data, 0, len);
apped2ByteBuffer(data);
}
private ByteBuffer buf = ByteBuffer.allocate(1024);
private void apped2ByteBuffer(byte[] data) {
for (byte b : data) {
if (b == 0x7E) {
// mark = position
buf.mark();
if (mark(buf) == 1 && buf.get(0) == 0x7E) continue;
// position++
buf.put(b);
// mark = position
buf.mark();
if (mark(buf) > 1) {
buf.flip();
byte[] out = new byte[buf.limit() - buf.position()];
buf.get(out);
if (out[0] == 0x7E && out[out.length - 1] == 0x7E) {
receive(addr, out);
// position = 0 ; limit = capacity ; mark = -1
buf.clear();
}
}
continue;
} else {
if (buf.get(0) == 0x7E) buf.put(b);
}
}
}
public static boolean msgCheck(byte[] pBuf) {
if (pBuf[0] != 0x7E || pBuf[pBuf.length - 1] != 0x7E) return false;
int count = 0;
for (int i = 1; i < pBuf.length - 1; i++) {
if (i == pBuf.length - 1 - 1) break;
if ((pBuf[i] == 0x7D && (pBuf[i] + pBuf[i + 1] == 0x7F)) || (pBuf[i] == 0x7D && (pBuf[i] + pBuf[i + 1] == 0x7E))) {
count++;
continue;
}
}
int MessageLength = pBuf.length - count;
byte[] bytes = new byte[MessageLength];
int MessageIndex = 0;
for (int i = 0; i < bytes.length; i++) {
if (pBuf[MessageIndex] == 0x7D && pBuf[MessageIndex] + pBuf[MessageIndex + 1] == 0x7F) {
bytes[i] = 0x7E;
MessageIndex += 2;
continue;
}
if (pBuf[MessageIndex] == 0x7D && pBuf[MessageIndex] + pBuf[MessageIndex + 1] == 0x7E) {
bytes[i] = pBuf[MessageIndex];
MessageIndex += 2;
continue;
}
bytes[i] = pBuf[MessageIndex];
MessageIndex++;
}
int CheckCode = 0;
for (int i = 1; i < bytes.length - 2; i++) CheckCode ^= bytes[i];
if (CheckCode == bytes[bytes.length - 2]) {
// int command = Byte2Int(new byte[] { bytes[1], bytes[2] });
// try {
// MessageParse(command, bytes);
// } catch (Exception e) {
// e.printStackTrace();
// }
return true;
}
return false;
}
private int mark(ByteBuffer buff) {
try {
Field field = buff.getClass().getSuperclass().getSuperclass().getDeclaredField("mark");
field.setAccessible(true);
return field.getInt(buff);
} catch (Exception e) {
e.printStackTrace();
}
return -100;
} */
/**
* 发送byte[]数据
* @param data
* 需要发送的内容
*/
void send(byte[] data) throws IOException {
if (outputStream == null) return;
if (data != null && data.length > 0) {
outputStream.write(data);
outputStream.flush();
}
}
/**
* 接收到数据
* 注意:此回调是在新线程中执行的
* @param addr
* 连接到的Socket地址
* @param s
* 收到的字符串
*/
abstract void receive(InetAddress addr, byte[] data);
/**
* 连接断开
* <p>
* 注意:此回调是在新线程中执行的
*
* @param addr
* 连接到的Socket地址
*/
abstract void disconnect(InetAddress addr);
}
//Socket的连接类,器主要作用是连接上后回调转态出去,
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
abstract class SocketConnector implements Runnable {
private static final String TAG = "SocketConnector";
private int port;
private String hostIP;
private volatile boolean connect = false;
private Socket socket;
private SocketTransceiver transceiver;
private SocketAddress mSocketAddress;
void connect(SessionConfig config) {
this.hostIP = config.getIp();
this.port = config.getPort();
new Thread(this, TAG).start();
}
private void connectSocket() {
if (mSocketAddress == null) {
mSocketAddress = new InetSocketAddress(hostIP, port);
}
if (transceiver == null) {
transceiver = new SocketTransceiver(socket) {
@Override
public void receive(InetAddress addr, byte[] data) {
SocketConnector.this.receive(this, data);
}
@Override
public void disconnect(InetAddress addr) {
connect = false;
SocketConnector.this.disconnect(this);
}
};
}
}
@Override
public void run() {
RmtLog.d(JSATLApp.TAG, " run() AAA ");
if (socket == null) {
try {
socket = new Socket(hostIP, port);
if (socket.isConnected()) {
connectSocket();
transceiver.start();
connect = true;
connectOk(transceiver);
}
} catch (IOException e) {
connect = false;
Log.d(TAG, "---BBB-----:"+ e.getMessage());
connectFailed(e);
}
}
}
void disconnect() {
RmtLog.d(JSATLApp.TAG, " SocketConnector disconnect() ");
try {
if (transceiver != null) {
transceiver.stop();
Log.d(App.TAG, " Receive stop() ");
}
transceiver = null;
if (socket != null) {
socket.close();
Log.d(App.TAG, " Socket close() ");
}
socket = null;
connect = false;
mSocketAddress = null;
Log.d(App.TAG, " Close All " + connect);
} catch (IOException e) {
e.printStackTrace();
Log.d(App.TAG, " Close All IOException " + e.getMessage());
}
}
/**
* 判断是否连接
* @return 当前处于连接状态,则返回true
*/
boolean isConnected() {
return connect;
}
/**
* 获取Socket收发器
*/
SocketTransceiver getTransceiver() {
return isConnected() ? transceiver : null;
}
/**
* 连接建立
*/
abstract void connectOk(SocketTransceiver transceiver);
/**
* 连接建立失败
*/
abstract void connectFailed(Exception e);
/**
* 接收到数据
* 注意:此回调是在新线程中执行的
*/
abstract void receive(SocketTransceiver transceiver, byte[] data);
/**
* 连接断开
* 注意:此回调是在新线程中执行的
* @param transceiver SocketTransceiver对象
*/
abstract void disconnect(SocketTransceiver transceiver);
}
//外部调用的类.通过该类即可实现
import java.io.IOException;
public class ConnectManager {
private static ConnectManager instance;
private SocketConnector connector;
private SocketTransceiver transceiver;
private ConnectListener listener;
public static ConnectManager asInstance() {
if (instance == null) {
synchronized (ConnectManager.class) {
if (instance == null) {
instance = new ConnectManager();
}
}
}
return instance;
}
private ConnectManager() {
connector = new SocketConnector() {
@Override
void receive(SocketTransceiver transceiver, byte[] data) {
if (listener != null) listener.receive(data);
}
@Override
void disconnect(SocketTransceiver transceiver) {
if (listener != null) listener.disconnect();
}
@Override
void connectOk(SocketTransceiver transceiver) {
ConnectManager.this.transceiver = transceiver;
if (listener != null) listener.connectOk();
}
@Override
void connectFailed(Exception e) {
if (listener != null) listener.connectFailed(e);
}
};
}
public void registerConnectListener(ConnectListener listener) {
this.listener = listener;
}
public void unregisterConnectListener() {
this.listener = null;
}
public void connect(SessionConfig config) {
if (connector == null) return;
connector.connect(config);
}
public boolean isConnect() {
if (connector == null) return false;
return connector.isConnected();
}
public void write(byte[] data) {
if (data == null || data.length == 0) return;
if (transceiver == null) return;
try {
if(connector.isConnected()) { // add
transceiver.send(data);
}
} catch (IOException e) {
e.printStackTrace();
connector.connectFailed(e);
}
}
public void disconnect() {
if (connector == null) return;
Log.d(App.TAG, " ConnectManager disconnect() ");
connector.disconnect();
}
public void release() {
unregisterConnectListener();
if (connector != null) {
connector.disconnect();
connector = null;
Log.d(LApp.TAG, " ConnectManager release) ");
}
transceiver = null;
instance = null;
Log.d(App.TAG, " Release All ");
}
}
调用方法如下 :
ConnectManager mConnector = ConnectManager.asInstance(); // 单列初始化
mConnector.connect(config); // 开始连接
mConnector.registerConnectListener(listener); // 设置一个监听
private ConnectListener listener = new ConnectListener() {
@Override
public void receive(byte[] s) {
// do Something 读取的数据接收
}
@Override
public void disconnect() {
// do Something 连接断开
}
@Override
public void connectOk() {
// do Something 连接OK
}
@Override
public void connectFailed(Exception e) {
// do Something 连接出错
}
};
到这里就结束了,是不是很简单呢,.赶紧下载使用吧