taxiapp/app/src/main/java/cn/trans88/taxiappkotlin/ledok/TaskSocketServer.kt

618 lines
22 KiB
Kotlin
Raw Normal View History

2024-11-05 19:25:55 +08:00
package cn.trans88.taxiappkotlin.ledok
import android.content.Context
import android.util.Log
import cn.trans88.taxiappkotlin.R
import cn.trans88.taxiappkotlin.TaxiApp
import cn.trans88.taxiappkotlin.logic.network.ConnManger
import com.google.gson.GsonBuilder
import com.trs88.kurolibrary.log.KuroLog
import java.io.BufferedReader
import java.io.DataOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.FileReader
import java.io.IOException
import java.io.InputStream
import java.net.ServerSocket
import java.net.Socket
import java.util.Timer
import java.util.TimerTask
import java.util.concurrent.TimeUnit
class TaskSocketServer(private val context: Context, port: Int) {
companion object {
val TAG: String = TaskSocketServer::class.java.simpleName
}
var timer: Timer? = null
private var file: File? = null
private var fos: FileOutputStream? = null
private var dos: DataOutputStream? = null
private var startFlag = 0
private var endFlag = 0
//private byte[] globleBuff = new byte[1020];
var m_iCurFileSize: Int = 0 //当前文件的大小
var m_iCurFileRecvLength: Int = 0 //当前文件接收到的字节
private val bFileOpr = false
var jsonBuff: ByteBuffer = ByteBuffer()
private var soc: ServerSocket? = null
private var client: Socket? = null
private val dir: String? = null
private var downloadDir: File? = null
private val prot = 3333
private var recreate = true
fun destroy() {
Log.i(TAG, "destroy killLive。。。。")
killLive()
clear()
if (client != null) {
try {
client!!.close()
} catch (e: IOException) {
e.printStackTrace()
}
client = null
}
try {
if (soc != null) soc!!.close()
soc = null
} catch (e: IOException) {
e.printStackTrace()
}
}
fun listen() {
Log.i(TAG, "listen")
keepLive()
while (soc != null && !soc!!.isClosed) {
try {
//只保持一个链接,新的进来就把老的断开
val socket = soc!!.accept()
2024-11-06 11:44:40 +08:00
socket.soTimeout = 5000 * 5
2024-11-05 19:25:55 +08:00
if (client != null) {
client!!.close()
}
client = socket
Log.i(TAG, "new client is connected")
clear()
//edit by ljh@2024/4/28 优化ledOk发节目旧连接没断开新连接发送不了数据问题
ThreadProcessor.getInstance().addThread {
recvDataFromClient()
}
} catch (e: Exception) {
Log.d(TAG, "Exception msg: " + e.message)
e.printStackTrace()
}
}
Log.i(TAG, "server 断开重建。。。。")
}
private fun keepLive() {
if (timer == null) {
timer = Timer()
timer!!.schedule(object : TimerTask() {
override fun run() {
if (soc != null && !soc!!.isClosed) {
Log.i(TAG, "server live 。。。。")
recreate = false
} else {
Log.i(TAG, "server death 。。。。")
recreate = true
}
}
}, 5000, (30 * 1000).toLong())
}
}
private fun killLive() {
Log.i(TAG, "killLive。。。。")
if (timer != null) {
timer!!.cancel()
timer = null
}
}
fun sendDataToClient(msg: String) {
try {
val bs = msg.toByteArray()
if (client != null) {
client!!.getOutputStream().write(bs)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun recvDataFromClient() {
var len = -1
val buff = ByteArray(4096)
var input: InputStream? = null
try {
input = client!!.getInputStream()
while ((input.read(buff).also { len = it }) != -1
) {
processData(buff, len)
}
} catch (e: Exception) {
e.printStackTrace()
Log.i(TAG, "出错重置。。。。")
clear();
try {
client?.close();
} catch (e: IOException) {
e.printStackTrace();
}
} finally {
clear()
if (input != null) {
try {
input.close()
} catch (e: IOException) {
throw RuntimeException(e)
}
}
if (client != null) {
try {
client!!.close()
} catch (e: IOException) {
throw RuntimeException(e)
}
}
}
}
fun clear() {
if (file != null) {
file!!.delete()
file = null
}
if (fos != null) {
try {
fos!!.close()
fos = null
} catch (e: IOException) {
e.printStackTrace()
}
}
if (dos != null) {
try {
dos!!.close()
dos = null
} catch (e: IOException) {
e.printStackTrace()
}
}
startFlag = 0
endFlag = 0
m_iCurFileSize = 0
m_iCurFileRecvLength = 0
jsonBuff.clear()
}
private fun processData(buff: ByteArray, len: Int) {
var i = 0
while (i < len) {
if (file != null) {
//文件已经打开说明已经收到了fileStart下面的数据准备写入文件
val iRestLength = len - i
// m_iCurFileSize表示 ledOk发过来文件的大小,m_iCurFileRecvLength表示 当前文件接收到的字,累加起来
val iRestFileLength = m_iCurFileSize - m_iCurFileRecvLength
// Log.d(
// TAG,
// "m_iCurFileSize:$m_iCurFileSize\nm_iCurFileRecvLength:$m_iCurFileRecvLength\niRestFileLength:$iRestFileLength"
// )
// Log.d(TAG, "processData: file: ")
//buff中剩余的字节数 大于 剩余未写入文件的字节数
if (iRestLength >= iRestFileLength) {
//并且剩余文件未写入字节数 大于 0
if (iRestFileLength > 0) {
//直接将iRestFileLength长度字节数写入文件buff索引向后移动iRestFileLength个字节
try {
val restBuff = ByteArray(iRestFileLength)
System.arraycopy(buff, i, restBuff, 0, iRestFileLength)
//// Log.i(TAG,"BS:"+Arrays.toString(restBuff));
if (fos == null) {
fos = FileOutputStream(file)
if (dos == null) {
dos = DataOutputStream(fos)
}
//Log.i(TAG,"BS:"+Arrays.toString(restBuff));
KuroLog.i("TAG:processData:0")
dos!!.write(restBuff)
} else {
if (dos == null) {
dos = DataOutputStream(fos)
}
//Log.i(TAG,"BS:"+Arrays.toString(restBuff));\
KuroLog.i("TAG:processData:1")
dos!!.write(restBuff)
}
m_iCurFileRecvLength += iRestFileLength
i += iRestFileLength
//文件写完了,关闭当前文件
startFlag = 0
} catch (e: Exception) {
//Log.i(tag, "10000000000000000000");
e.printStackTrace()
}
} else {
//Log.i(tag, "iRestFileLength <= 0");
if (iRestFileLength < 0) {
Log.i(TAG, "iRestFileLength < 0")
}
}
} else {
try {
val restBuff = ByteArray(iRestLength)
//// Log.i(TAG,"BS:"+Arrays.toString(restBuff));
System.arraycopy(buff, i, restBuff, 0, iRestLength)
//Log.i(tag, "00");
if (file != null) {
//Log.i(tag, "01");
if (fos == null) {
fos = FileOutputStream(file)
if (dos == null) {
dos = DataOutputStream(fos)
}
KuroLog.i("TAG:processData:2")
dos!!.write(restBuff)
} else {
if (dos == null) {
dos = DataOutputStream(fos)
}
// KuroLog.i("TAG:processData:3");
dos!!.write(restBuff)
}
}
m_iCurFileRecvLength += iRestLength
} catch (e: Exception) {
//Log.i(tag, "1111111111111111111111111");
e.printStackTrace()
}
return
}
}
//
if (startFlag == 0) {
if (buff[i] == '{'.toByte()) {
startFlag = 1
jsonBuff.append(buff[i])
}
} else if (startFlag == 1) {
if (buff[i] == '"'.toByte()) {
startFlag = 2
jsonBuff.append(buff[i])
} else {
startFlag = 0
jsonBuff.clear()
}
} else if (startFlag == 2) {
if (buff[i] == '_'.toByte()) {
startFlag = 3
jsonBuff.append(buff[i])
} else {
startFlag = 0
jsonBuff.clear()
}
} else if (startFlag == 3) {
if (buff[i] == 't'.toByte()) {
startFlag = 4
jsonBuff.append(buff[i])
} else {
startFlag = 0
jsonBuff.clear()
}
} else if (startFlag == 4) {
if (buff[i] == 'y'.toByte()) {
startFlag = 5
jsonBuff.append(buff[i])
} else {
startFlag = 0
jsonBuff.clear()
}
} else if (startFlag == 5) {
if (buff[i] == 'p'.toByte()) {
startFlag = 6
jsonBuff.append(buff[i])
} else {
startFlag = 0
jsonBuff.clear()
}
} else if (startFlag == 6) {
if (buff[i] == 'e'.toByte()) {
startFlag = 7
jsonBuff.append(buff[i])
} else {
startFlag = 0
jsonBuff.clear()
}
} else if (startFlag == 7) {
if (endFlag == 0) {
if (buff[i] == 'x'.toByte()) {
endFlag = 1
}
} else if (endFlag == 1) {
endFlag = if (buff[i] == 'i'.toByte()) {
2
} else {
0
}
} else if (endFlag == 2) {
endFlag = if (buff[i] == 'x'.toByte()) {
3
} else {
0
}
} else if (endFlag == 3) {
endFlag = if (buff[i] == 'u'.toByte()) {
4
} else {
0
}
} else if (endFlag == 4) {
endFlag = if (buff[i] == 'n'.toByte()) {
5
} else {
0
}
} else if (endFlag == 5) {
endFlag = if (buff[i] == '1'.toByte()) {
6 //jsonObject结束
} else {
0
}
} else if (endFlag == 6) {
endFlag = if (buff[i] == '"'.toByte()) {
7 //jsonObject结束
} else {
0
}
} else if (endFlag == 7) {
endFlag = if (buff[i] == '}'.toByte()) {
8 //jsonObject结束
} else {
0
}
}
jsonBuff.append(buff[i])
if (endFlag == 8) {
val json = String(jsonBuff.buff, 0, jsonBuff.len())
processPackage(json)
endFlag = 0
startFlag = endFlag
jsonBuff.clear()
}
}
i++
}
}
fun processPackage(json: String?) {
if (json != null) {
try {
val gson = GsonBuilder().serializeNulls().create()
val cmd = gson.fromJson(json, JsonCommand::class.java)
if (cmd._type == "consult") {
Log.d(TAG, "processPackage([json]): consult: $json")
idList1 = cmd.idList
ackList(cmd.idList)
} else if (cmd._type == "proStart") {
Log.d(TAG, "processPackage([json]): proStart: $json")
} else if (cmd._type == "proEnd") {
Log.d(TAG, "processPackage([json]): proEnd: $json")
val ack = "{\"_type\":\"AckSuccess\"}"
sendDataToClient(ack)
client?.close()
Log.d(TAG, "processPackage([json]): ack: $ack")
//文件接收完成,可以开始播放
LedOkCommands.startLedOkActivity()
} else if (cmd._type == "fileStart") {
Log.d(TAG, "processPackage([json]): fileStart: $json")
m_iCurFileSize = cmd.size
m_iCurFileRecvLength = 0
if (!cmd.id!!.isEmpty() && file == null) {
if (!downloadDir?.exists()!!) {
downloadDir?.mkdirs();
}
var path = "${downloadDir?.absolutePath}/${cmd.id}"
file = File(path);
if (!file!!.exists()) {
Log.i(TAG, "create file :" + path);
file!!.createNewFile();
}
file!!.setWritable(true, true);
} else if (!cmd.id!!.isEmpty() && file != null) {
if (!file!!.canWrite()) {
file!!.setWritable(true, true)
}
}
} else if (cmd._type == "fileEnd") {
Log.d(TAG, "processPackage([json]): fileEnd: $json")
if (dos != null) {
dos!!.flush()
//将数据同步到达物理存储设备
val fd = fos!!.fd
fd.sync()
dos!!.close()
}
if (fos != null) fos!!.close()
file!!.setWritable(false, true);
fos = null
dos = null
file = null
//TaskProcessor.getInstance(context).updateSourceFile(new SourceFile(cmd.id, servant.getCanUsedPath(context), FileState.Is_Downloaded));
2024-11-06 11:44:40 +08:00
}
// else if (cmd._type == "BindAccount") {
// Log.d(TAG, "processPackage: BindAccount")
// val server = cmd.server!!
// val tlsServer = cmd.tlsServer!!
// val accountIdToken = cmd.accountIdToken!!
// val bindModel = BindModel("", accountIdToken, server, tlsServer)!!
// if (bindModel?.server != null && bindModel?.server != "") {
// bindModel?.server = bindModel?.server + "/"
2024-11-05 19:25:55 +08:00
// }
2024-11-06 11:44:40 +08:00
// if (bindModel?.server != null && bindModel.server != "") {
// bindModel.tlsServer = bindModel.tlsServer + "/"
2024-11-05 19:25:55 +08:00
// }
2024-11-06 11:44:40 +08:00
// val mbindAccount = ConnManger.mbindAccount(bindModel)
2024-11-05 19:25:55 +08:00
// if (mbindAccount == true) {
// val ack = "{\"_type\":\"AckSuccess\"}"
// sendDataToClient(ack)
// } else {
// val ack = "{\"_type\":\"AckFailed\"}"
// sendDataToClient(ack)
// }
// client?.close()
2024-11-06 11:44:40 +08:00
// }
2024-11-05 19:25:55 +08:00
} catch (e: Exception) {
Log.i(TAG, "error:" + e.message)
e.printStackTrace()
}
}
}
fun ackList(list: List<String>?) {
if (list.isNullOrEmpty()) {
Log.i(TAG, "consult is empty")
return
}
val downloadList: MutableList<String> = ArrayList()
for (id in list) {
val file = File("${downloadDir?.absolutePath}/${id}")
if (id == "program" || !file.exists()) {
downloadList.add(id)
}
}
var sl = ""
for (i in downloadList.indices) {
sl = if (i == 0) {
sl + "\"" + downloadList[i] + "\""
} else {
sl + ",\"" + downloadList[i] + "\""
}
}
val ack = "{\"_type\":\"consult\",\"idList\":[$sl]}"
Log.d(TAG, "processPackage([json]): ack: $ack")
sendDataToClient(ack)
//发送出去
}
inner class ByteBuffer {
var buff: ByteArray
private val unit = 3000
private var size: Int
private var index: Int
init {
buff = ByteArray(unit)
size = unit
index = 0
}
fun append(b: Byte) {
if (index >= size) {
Log.i(TAG, "================ index of ByteBuffer > size===============")
size = size + unit
val temp = ByteArray(size)
System.arraycopy(buff, 0, temp, 0, index)
buff = temp
}
buff[index] = b
index++
}
fun clear() {
buff = ByteArray(unit)
size = unit
index = 0
}
fun len(): Int {
return index
}
}
inner class JsonCommand {
var _type: String? = null
var proName: String? = null
var proSize: Int = 0
var zVer: String? = null
var id: String? = null
var relative_path: String? = null
var size: Int = 0
var data: String? = null
var _id: String? = null
var idList: List<String>? = null
var task: Task? = null
2024-11-06 11:44:40 +08:00
// var bindModel: cn.trans88.taxiappkotlin.ledok.BindModel? = null
var accountIdToken: String? = null
var server: String? = null
var tlsServer: String? = null
2024-11-05 19:25:55 +08:00
}
var idList1: List<String>? = null
init {
downloadDir =
File(TaxiApp.instance().filesDir, TaxiApp.instance().getString(R.string.dir_program))
Log.d(TAG, "downloadDir: $downloadDir")
while (recreate) {
try {
// if (soc == null) {
// destroy()
2024-11-06 11:44:40 +08:00
soc = ServerSocket(port)
recreate = false
2024-11-05 19:25:55 +08:00
// }
Log.i(TAG, "create...... ")
} catch (e: Exception) {
Log.i(TAG, e.message + "...............")
try {
TimeUnit.SECONDS.sleep(1)
} catch (interruptedException: InterruptedException) {
interruptedException.printStackTrace()
}
}
}
}
fun readFileContent(fileName: String?): String? {
val file = File(fileName)
if (!file.exists()) {
return null
}
var reader: BufferedReader? = null
val sbf = StringBuffer()
try {
reader = BufferedReader(FileReader(file))
var tempStr: String?
while ((reader.readLine().also { tempStr = it }) != null) {
sbf.append(tempStr)
}
reader.close()
return sbf.toString()
} catch (e: IOException) {
e.printStackTrace()
} finally {
if (reader != null) {
try {
reader.close()
} catch (e1: IOException) {
e1.printStackTrace()
}
}
}
return sbf.toString()
}
}