205 lines
11 KiB
Java
205 lines
11 KiB
Java
![]() |
package com.xixun.xixunplayer;
|
||
|
|
||
|
import android.app.ActivityManager;
|
||
|
import android.graphics.BitmapFactory;
|
||
|
import android.os.Environment;
|
||
|
import android.os.StatFs;
|
||
|
|
||
|
import java.io.ByteArrayOutputStream;
|
||
|
import java.io.File;
|
||
|
import java.io.FileInputStream;
|
||
|
import java.io.FileOutputStream;
|
||
|
import java.io.InputStream;
|
||
|
import java.io.OutputStream;
|
||
|
import java.io.OutputStreamWriter;
|
||
|
import java.net.ServerSocket;
|
||
|
import java.net.Socket;
|
||
|
import java.net.SocketTimeoutException;
|
||
|
import java.text.SimpleDateFormat;
|
||
|
import java.util.Arrays;
|
||
|
import java.util.Date;
|
||
|
import java.util.HashSet;
|
||
|
import java.util.TimeZone;
|
||
|
import java.util.concurrent.CountDownLatch;
|
||
|
|
||
|
import gnph.util.IOs;
|
||
|
import gnph.util.JSList;
|
||
|
import gnph.util.JSMap;
|
||
|
import gnph.util.NumFmts;
|
||
|
import gnph.util.O;
|
||
|
|
||
|
public class TCPThread extends Thread {
|
||
|
|
||
|
public static void startServer(int port) {
|
||
|
new Thread(()->{
|
||
|
try {
|
||
|
var serverSocket = new ServerSocket(port);
|
||
|
while(true) {
|
||
|
try {
|
||
|
Util.println("\nAccepting ...");
|
||
|
var socket = serverSocket.accept();
|
||
|
new TCPThread(MainActivity.ins, socket).start();
|
||
|
Util.println("\nAccepted");
|
||
|
} catch (Throwable e) {
|
||
|
var ins = MainActivity.ins;
|
||
|
if(ins!=null) ins.runOnUiThread(() -> Util.makeText(ins, Util.toStr(e)).show());
|
||
|
Util.printStackTrace(e);
|
||
|
}
|
||
|
}
|
||
|
} catch (Throwable e) {
|
||
|
var msg = e.getMessage();
|
||
|
if(msg==null || ! msg.contains("in use")) MainActivity.ins.runOnUiThread(() -> Util.makeText(MainActivity.ins, Util.toStr(e)).show());
|
||
|
Util.printStackTrace(e);
|
||
|
}
|
||
|
}).start();
|
||
|
}
|
||
|
|
||
|
MainActivity main;
|
||
|
Socket socket;
|
||
|
InputStream in;
|
||
|
OutputStream out;
|
||
|
SimpleDateFormat fmt = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
|
||
|
|
||
|
public TCPThread(MainActivity main, Socket socket) {
|
||
|
this.main = main;
|
||
|
this.socket = socket;
|
||
|
}
|
||
|
public void run() {
|
||
|
try {
|
||
|
socket.setSoTimeout(600000);
|
||
|
Util.socketThreads.add(this);
|
||
|
in = socket.getInputStream();
|
||
|
out = socket.getOutputStream();
|
||
|
HashSet<String> existed = null;
|
||
|
ByteArrayOutputStream progJson = null;
|
||
|
while(true) {
|
||
|
var obj = JSMap.from(in);
|
||
|
var _type = obj.stnn("_type");
|
||
|
Util.println("_type: "+_type);
|
||
|
if("consult".equals(_type)) {
|
||
|
JSList<JSMap> files = obj.jslist("files");
|
||
|
if(files==null) new JSMap("_type", _type, "idList", obj.jslist("idList")).write(out);
|
||
|
else {
|
||
|
existed = new HashSet<>();
|
||
|
for(var fil : files) {
|
||
|
var name = fil.stnn("name");
|
||
|
var file = new File(Util.programDir + "/" + name);
|
||
|
if(file.isFile() && file.length()==fil.intg("size")) existed.add(name);
|
||
|
}
|
||
|
new JSMap("_type", _type, "existed", existed).write(out);
|
||
|
}
|
||
|
} else if("setBackImg".equals(_type) || "imgFileStart".equals(_type)) {
|
||
|
var fout = new FileOutputStream(Util.backImgFile);
|
||
|
IOs.write(fout, in, obj.intg("size"));
|
||
|
fout.flush();
|
||
|
fout.getFD().sync();
|
||
|
fout.close();
|
||
|
var img = BitmapFactory.decodeFile(Util.backImgFile, Util.noScaled);
|
||
|
if(main!=null) main.runOnUiThread(() -> {
|
||
|
main.backView.cosImg = img;
|
||
|
main.backView.invalidate();
|
||
|
});
|
||
|
new JSMap("success", true).write(out);
|
||
|
} else if("DelBackImg".equals(_type)) {
|
||
|
MainActivity.ins.runOnUiThread(() -> {
|
||
|
MainActivity.ins.backView.cosImg = null;
|
||
|
MainActivity.ins.backView.invalidate();
|
||
|
});
|
||
|
new JSMap("success", new File(Util.backImgFile).delete()).write(out);
|
||
|
} else if("Config".equals(_type)) {
|
||
|
var entrySet = obj.entrySet();
|
||
|
for(var entry : entrySet) if(! entry.getKey().equals("_type")) Util.cfg.put(entry.getKey(), entry.getValue());
|
||
|
try (var fOut = new FileOutputStream(Util.programDir + "/cfg")) {
|
||
|
Util.cfg.write(fOut);
|
||
|
fOut.flush();
|
||
|
fOut.getFD().sync();
|
||
|
}
|
||
|
new JSMap("success", new File(Util.backImgFile).delete()).write(out);
|
||
|
} else if("GetInfo".equals(_type)) {
|
||
|
var writer = new OutputStreamWriter(out);
|
||
|
var fmt = new SimpleDateFormat("yy-MM-dd HH:mm:ss.SSS");
|
||
|
writer.append(" Current: ").append(fmt.format(System.currentTimeMillis())).append(" ").append(String.valueOf(TimeZone.getDefault().getRawOffset()/3600000f)).append(" ").append(TimeZone.getDefault().getDisplayName()).append("\n");
|
||
|
|
||
|
var statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
|
||
|
writer.append(" Disk: ").append(String.valueOf(statFs.getTotalBytes()/1000000)).append(" ").append(String.valueOf(statFs.getAvailableBytes()/1000000)).append(" ").append(String.valueOf(statFs.getFreeBytes()/1000000)).append(" (total avail free)\n");
|
||
|
if(main!=null) {
|
||
|
var actManager = (ActivityManager) main.getSystemService(MainActivity.ACTIVITY_SERVICE);
|
||
|
var memoryInfo = new ActivityManager.MemoryInfo();
|
||
|
actManager.getMemoryInfo(memoryInfo);
|
||
|
writer.append(" Memory: ").append(String.valueOf(memoryInfo.totalMem/1000000)).append(" ").append(String.valueOf(memoryInfo.availMem/1000000)).append(" ").append(String.valueOf(memoryInfo.threshold/1000000)).append(" ").append(String.valueOf(memoryInfo.lowMemory)).append(" (total avail threshold low)\n");
|
||
|
}
|
||
|
var runtime = Runtime.getRuntime();
|
||
|
writer.append("Runtime: ").append(String.valueOf(runtime.maxMemory()/1000000)).append(" ").append(String.valueOf(runtime.totalMemory()/1000000)).append(" ").append(NumFmts.cfix2().format(runtime.freeMemory()*0.000001)).append(" (max total free)\n");
|
||
|
writer.append("\nSockets ").append(String.valueOf(Util.socketThreads.size())).append("\n");
|
||
|
for(var socket : Util.socketThreads) writer.append(" ").append(String.valueOf(socket.socket.getInetAddress())).append(":").append(String.valueOf(socket.socket.getPort())).append(" Buf:").append(String.valueOf(socket.socket.getReceiveBufferSize()/1000)).append("k SoLinger:").append(String.valueOf(socket.socket.getSoLinger())).append("\n");
|
||
|
|
||
|
writer.append("\n\n");
|
||
|
writer.append(Util.cfg.toStr());
|
||
|
writer.append("\n\n");
|
||
|
|
||
|
var latch = new CountDownLatch(1);
|
||
|
try {
|
||
|
latch.await();
|
||
|
} catch (InterruptedException ignored) {}
|
||
|
writer.flush();
|
||
|
} else if("ListProgFiles".equals(_type)) {
|
||
|
var files = new File(Util.programDir).listFiles();
|
||
|
if(files!=null) {
|
||
|
Arrays.sort(files, (f1, f2) -> Long.signum(f2.lastModified() - f1.lastModified()));
|
||
|
var writer = new OutputStreamWriter(out);
|
||
|
for(var file : files) writer.append(fmt.format(new Date(file.lastModified()))).append(' ').append(file.getName()).append(' ').append(String.valueOf(file.length())).append('\n');
|
||
|
writer.flush();
|
||
|
}
|
||
|
} else if("GetFile".equals(_type)) {
|
||
|
var name = obj.str("name");
|
||
|
if(name==null) new JSMap("msg", "name is null").write(out);
|
||
|
else {
|
||
|
var file = new File(Util.programDir+"/"+name);
|
||
|
if(! file.isFile()) new JSMap("msg", "file not exist").write(out);
|
||
|
else {
|
||
|
new JSMap("len", file.length()).write(out);
|
||
|
IOs.writeCloseIn(out, new FileInputStream(file));
|
||
|
}
|
||
|
}
|
||
|
} else if("GetJsonWithFileInfo".equals(_type)) {
|
||
|
var inse = new File(Util.programDir+"/insert");
|
||
|
var files = new File(Util.programDir).listFiles();
|
||
|
if(inse.isFile()) {
|
||
|
var json = IOs.readStrClose(new FileInputStream(inse));
|
||
|
if(files!=null) for(var file : files) if(! "program".equals(file.getName())) json = json.replace("\""+file.getName()+"\"", "\""+file.getName()+"\"/*"+file.length()+" "+fmt.format(new Date(file.lastModified()))+"*/");
|
||
|
var writer = new OutputStreamWriter(out);
|
||
|
writer.append("insert:\n");
|
||
|
writer.append(json);
|
||
|
if(! json.endsWith("\n")) writer.append("\n");
|
||
|
writer.flush();
|
||
|
}
|
||
|
var prog = new File(Util.programDir+"/program");
|
||
|
if(! prog.isFile()) new JSMap("msg", "'program' file not exist").write(out);
|
||
|
else {
|
||
|
var json = IOs.readStrClose(new FileInputStream(prog));
|
||
|
if(files!=null) for(var file : files) if(! "program".equals(file.getName())) json = json.replace("\""+file.getName()+"\"", "\""+file.getName()+"\"/*"+file.length()+" "+fmt.format(new Date(file.lastModified()))+"*/");
|
||
|
var writer = new OutputStreamWriter(out);
|
||
|
writer.append("\nprogram:\n");
|
||
|
writer.append(json);
|
||
|
writer.flush();
|
||
|
}
|
||
|
}
|
||
|
out.flush();
|
||
|
Util.println("cmd end");
|
||
|
}
|
||
|
} catch (Throwable e) {
|
||
|
var emsg = e.getMessage();
|
||
|
if(e instanceof SocketTimeoutException || "Socket closed".equals(emsg) || (emsg!=null && emsg.endsWith("end-of-input"))) {
|
||
|
Util.println(emsg);
|
||
|
return;
|
||
|
}
|
||
|
if(main!=null) main.runOnUiThread(() -> Util.makeText(main, Util.toStr(e)).show());
|
||
|
Util.printStackTrace(e);
|
||
|
} finally {
|
||
|
Util.socketThreads.remove(this);
|
||
|
O.close(in, out, socket);
|
||
|
Util.println("conn end\n");
|
||
|
}
|
||
|
}
|
||
|
}
|