背景
获取相机的数据流,转成bitmap,将图片数据通过TCP发送到服务器进行业务处理。
package org.venus.ar.ocr.net.tcp;
import android.graphics.Bitmap;
import android.util.Base64;
import org.venus.ar.ocr.common.Config;
import java.io.*;
import java.net.Socket;
import java.nio.charset.Charset;
/**
* @Author Jxx 让世界看到我
* @Create 2022/7/14 11:26
* @Note TODO
*/
public class TCPClient {
private String ip;
private int port;
private OnServerListen mOnServerListen;
private Socket socket;
private OutputStream os;
private static TCPClient instance;
public static TCPClient getInstance(String ip, int port, OnServerListen onServerListen) {
if (instance == null) {
synchronized (TCPClient.class) {
if (instance == null) {
instance = new TCPClient(ip, port, onServerListen);
}
}
}
return instance;
}
private TCPClient(String ip, int port, OnServerListen onServerListen) {
this.ip = ip;
this.port = port;
this.mOnServerListen = onServerListen;
}
public void open() {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("连接TCP服务器:" + ip + ":" + port);
socket = new Socket(ip, port);
os = socket.getOutputStream();
while (true) {
DataInputStream input = new DataInputStream(socket.getInputStream());
byte[] buffer = new byte[input.available()];
if (buffer.length != 0) {
//System.out.println("buffer.length:"+buffer.length);
input.read(buffer);
String content = new String(buffer);
//System.out.println("收到消息:"+content);
if (mOnServerListen != null) {
mOnServerListen.rec(content);
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("服务器打开失败");
} finally {
close();
}
}
}).start();
}
public void close() {
if (mOnServerListen != null) {
mOnServerListen.resume();
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public boolean isConn() {
if (socket == null) {
return false;
}
if (socket.isClosed()) {
return false;
}
if (socket.isConnected() && socket.isBound()) {
return true;
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public String bitmap2BASE64(Bitmap bitmap) {
String result = null;
ByteArrayOutputStream baos = null;
try {
if (bitmap != null) {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
public void send(Bitmap bitmap) {
String base64 = bitmap2BASE64(bitmap);
//System.out.println("base64:"+base64.length());
if (base64 == null) {
System.out.println("bitmap转base64失败");
return;
}
send((base64 + Config.TAG_ENDING).getBytes(Charset.defaultCharset()));
}
public void send(byte[] data) {
if (!isConn()) {
System.out.println("连接已经断开,不能发送数据");
close();
return;
}
if (os == null) {
System.out.println("连接通道已经断开,不能发送数据");
close();
return;
}
try {
os.write(data);
} catch (IOException e) {
System.out.println("消息发送失败,准备关闭连接");
close();
e.printStackTrace();
}
}
public interface OnServerListen {
void rec(String data);
void resume();
}
}
定义TCP客户端类,提供几个函数,主要包括打开连接、发送数据等。
建立连接后拿到连接的输入对象阻塞线程用来读取服务端发送过来的数据。
发送数据中需要的是byte[],我们想要发送bitmap对象,需要将bitmap转成byte[],思路是将bitmap进行BASE64格式编码,转成字符串,这个BASE64字符串很大,发送到服务端会出现半包现象,所以在数据最后加上一个结束标识符,这个标识符是一个任意字符串,只有一点要保证,就是不能与BASE64字符串中的内容相同。否则服务端解码就会去解析出现结束符的一部分数据。
网友评论