这次是在云端用java写一个serversocket来监听客户端socket的连接请求。
总体的结构就是启动一个监听线程,如果监听到了客户端的连接请求,就另外启动一个子线程去负责和此客户端的交互,直至客户端发完数据,主动关闭socket,此时服务端的子线程socket也就关闭了。代码如下:
package com.example.socket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketTimeoutException; public class SSocket { public static final String TAG = "SSocket"; private StringBuffer debug_buffer = new StringBuffer(); public static final boolean ISDEBUG = true; private ServerSocket serverSocket = null; private boolean isStop = false; private static final int BUFFER_LENGTH = 4096; private DataOperator dataOperator = null; public SSocket(int port) { //启动监听线程 try { serverSocket = new ServerSocket(port); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //实例化数据处理类 dataOperator = new DataOperator(); //启动监听线程 Config.getExecutor().submit(new ListenRunnable()); } public void closeSocket() { if(serverSocket!=null) { try { serverSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } serverSocket=null; } isStop = true; } public class ListenRunnable implements Runnable { @Override public void run() { // TODO Auto-generated method stub while(!isStop) { try { //监听client的连接请求 Socket client = serverSocket.accept(); client.setSoTimeout(6000); //监听到了请求之后,另起线程与其交互 Config.getExecutor().submit(new ExcecuteRunnable(client)); } catch (IOException e) { try { Thread.sleep(400); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } System.out.println("exit Listen runnable"); } } public class ExcecuteRunnable implements Runnable { Socket socket = null; InputStream ins = null; OutputStream ous = null; byte[] buffer = null; int size = 0; int start = 0; int offsize = 0; public ExcecuteRunnable(Socket socket) { this.socket = socket; try { ins = socket.getInputStream(); ous = socket.getOutputStream(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //每一个交互线程启动一个接收数据的buffer buffer = new byte[BUFFER_LENGTH]; } @Override public void run() { // TODO Auto-generated method stub while(!isStop) { if(ins != null && buffer != null) { try { size = ins.read(buffer, offsize, BUFFER_LENGTH-offsize); if(size > 0) { start = offsize; //把offsize移位到数据的最后,即0x03的后一位,也就是下次接收数据的开始处 offsize = (offsize + size)%BUFFER_LENGTH; if(ISDEBUG) { debug_buffer.append("offsize = "+offsize+"\nbuffer = "+Funs.bytesToHexStr(buffer, 0, offsize)); // Log.i(TAG,debug_buffer.toString()); System.out.println(debug_buffer.toString()); debug_buffer.setLength(0); } //判断接收到的数据的末位是否为03,如果是的话就表示接收的是一个完整数据,02开始03结束 if(buffer[(offsize - 1+BUFFER_LENGTH)%BUFFER_LENGTH] == (byte)0x03) { byte[] sendData = dataOperator.oprData(buffer,start,offsize,BUFFER_LENGTH); ous.write(sendData); } else { //数据还没有完整接收,因为是在buffer的最后了,需要从buffer的开始接收数据的后半部分 continue; } } else if(size == -1) { //client close socket,所以此交互线程也要跳出while并结束了 break; } } catch(SocketTimeoutException ste) { System.err.println("SocketTimeoutException"); continue; } catch (IOException e) { System.err.println("IOException"); e.printStackTrace(); break; } } else { System.err.println("buffer = null"); break; } }//end while System.out.println("exit socket runnable"); try { if(socket != null) { socket.close(); socket = null; } if(ins != null) { ins.close(); ins = null; } if(ous != null) { ous.close(); ous = null; } } catch (IOException e) { e.printStackTrace(); } }//end run } }
public synchronized byte[] oprData(byte[] buffer, int start, int offsize, int bufferLength) { byte[] sendData = null; int head = start; int tail = offsize; int i = head; while(i != tail) { if(buffer[i] == (byte)0x02) { head = i; } else if(buffer[i] == (byte)0x03) { int len = (i-head+bufferLength+1)%bufferLength; if(len > 8) { if(check(buffer,head,(i+1)%bufferLength,bufferLength)) { String jsonString = null; byte[] data = new byte[len-8]; if(i > head) {//03在02后面 System.arraycopy(buffer, head+5, data, 0, len-8); } else {//03再02之前 System.arraycopy(buffer, (head+5)%bufferLength, data, 0, bufferLength-(head+5)%bufferLength); System.arraycopy(buffer, 0, data, bufferLength - (head+5)%bufferLength, len-8-bufferLength+(head+5)%bufferLength); } String hexString = new String(data,0,data.length); byte[] hexByte = Funs.HexStringToBytes(hexString); byte[] mData = EncDec.dec_3Des(hexByte, Config.pKey); jsonString = new String(mData); sendData = getServerData(jsonString); } else { System.err.println("data check error"); } } } i = (i+1)%bufferLength; } return sendData; }
getServerData就是从云端得到client想要得到的数据并传给client。
dataOperator.oprData(buffer,start,offsize,BUFFER_LENGTH);
替换为通过handler给service发消息,并把offsize传递过去
if(handler != null) {
handler.obtainMessage(0x123, (Integer)offsize).sendToTarget();
}
service收到此消息,就会开始进行数据处理。当然,在service中也会有两个int的变量,标记buffer上一次存到哪里了,这一次从哪里开始处理,因为传过来的只是buffer的结束位置,并没有开始位置。
data_end = obj2Integer(msg.obj);
oprData();
data_begin = data_end;