这次的项目JT/T 808协议使用Socket通讯,对原生的Socket研究了一下,把使用方法和心得写一下;
这个时必须要加的权限:
<uses-permission android:name="android.permission.INTERNET" />
Android主线程中不允许做耗时操作,Socket需要放在子线程中;
1、创建Socket连接,拿到输入输出流:
private Socket socket;
private DataInputStream dis;
private OutputStream out;
/**
* 创建socket客户端
*/
private void create() {
if (socket == null) socket = new Socket();
try {
socket.connect(new InetSocketAddress(IP, Integer.valueOf(PORT)), 5 * 1000);
if (socket.isConnected()) {
out = socket.getOutputStream();
InputStream in = socket.getInputStream();
dis = new DataInputStream(in);
String s = "服务器连接成功!";
Log.d(TAG, s);
}
} catch (IOException e) {
e.printStackTrace();
if (e instanceof SocketTimeoutException) {
// toastMsg("连接超时,正在重连");
} else if (e instanceof NoRouteToHostException) {
// toastMsg("该地址不存在,请检查");
} else if (e instanceof ConnectException) {
// toastMsg("连接异常或被拒绝,请检查");
} else if (e instanceof SocketException){
// if (TextUtils.equals(e.getMessage(),"already connected"))
// toastMsg("当前已连接,请勿再次连接");
}
} catch (Exception e) {
e.printStackTrace();
}
}
2、连接成功后发送消息:
/**
* 发送消息
*/
public synchronized void sendMsg(byte[] msg) {
try {
if (null != out) {
out.write(msg);
out.flush();
}
} catch (Exception e) {
//出现此异常说明Socker已经断开连接 断线重连
if (e instanceof SocketException) {
reconnectServer();
}
e.printStackTrace();
}
}
/**
* 重连tcp
*/
private void reconnectServer() {
try {
socket = new Socket(IP, PORT);
socket.setSoTimeout(5000);
out = socket.getOutputStream();
InputStream in = socket.getInputStream();
dis = new DataInputStream(in);
String s = "断线重连服务器: " + IP + ":" + PORT + " 连接成功!";
Log.d(TAG, s);
} catch (Exception e) {
e.printStackTrace();
}
}
3、接收消息,Socket在读取消息时线程属于堵塞状态,连接成功后就可以直接调用接收消息的方法:
while (true) {
try {
byte[] buff = new byte[1024];
int len = dis.read(buff);
byte[] data = Arrays.copyOfRange(buff, 0, len);
Log.i(TAG, "run: "+ HexUtil.byte2HexStr(data));
} catch (Exception e) {
e.fillInStackTrace();
}
}
注意:很多的文章都写着使用readLine方法读取消息,如果使用 readLine()方法读取消息时,只有遇到换行符才会继续读取,不建议使用此方法读取消息;
附:
下载一个“网络调试助手”就可以开始调试了;
这个日志输入有点磕碜,哈哈;
代码封装了一下,在线程池中做的处理;