最近在實現socket通訊,因此寫個demo來簡單實現下。我用了一種是原始的socket實現,另外一種是MINA框架來實現的。java
下載demo:http://download.csdn.net/detail/qq_29774291/9826648android
一.先看第一種方法apache
a)、建立Socket對象,指明須要鏈接的服務器的地址和端口。服務器
b)、創建鏈接後,經過輸出流向服務器發送請求信息。session
c)、經過輸入流獲取服務器的響應信息。app
d)、關閉響應資源框架
以下是主要代碼socket
package com.item.item.sock.socket; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.SystemClock; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; /** * Socket 通訊 */ public class MyServiceOne extends Service { private Socket socket; private BufferedReader in = null; private BufferedWriter out = null; private boolean close = true; private Thread readThread; @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); close = true; new Thread(new Runnable() { @Override public void run() { int count = 0; for(;;){ try { count++; SocketAddress socketAddress = new InetSocketAddress(ConnectUtils.HOST,ConnectUtils.POST); socket = new Socket(); socket.connect(socketAddress,10000); if(socket.isConnected()){ System.out.println("socket 鏈接成功"); in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8")); out =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8")); //發送一個消息 out.write("start"); out.flush(); //開啓一個線程來讀取服務器發來的消息 readThread.start(); break; } }catch (Exception e){ if(count > ConnectUtils.IDLE_TIME){ break; }else { SystemClock.sleep(5000); } } } } }).start(); readThread = new Thread(new Runnable() { @Override public void run() { while (close){ String readtext = readText(socket); if(readtext !=null){ System.out.println("服務器發來的消息:" + readtext); } } } }); } private String readText(Socket socket) { String string = null; if(socket.isConnected()){ try { char[] buffer = new char[8000]; int count = 0; if((count = in.read(buffer)) > 0){ char[] temp = new char[count]; for(int i=0;i<count;i++){ temp[i] = buffer[i]; } string = new String(temp); } }catch (Exception e){ string = null; } } return string; } @Override public void onDestroy() { super.onDestroy(); close = false; if(socket != null){ try { socket.close(); socket = null; } catch (IOException e) { e.printStackTrace(); } } } }
二.第二種方法是用MINA框架實現的ide
package com.item.item.sock.socket; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.SystemClock; import android.util.Log; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.service.IoService; import org.apache.mina.core.service.IoServiceListener; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.transport.socket.nio.NioSocketConnector; import java.net.InetSocketAddress; import java.nio.charset.Charset; /** * 使用MINA框架實現socket通訊 * 因爲接受消息會阻塞Android線程,因此開在子線程中(同時將其放在Service中,讓其在後臺運行) */ public class MyServiceTwo extends Service { private String TAG = "jiejie"; private IoSession session = null; private MinaClientHandler minaClientHandler; private NioSocketConnector connector = null; @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); minaClientHandler = new MinaClientHandler(); new Thread(new Runnable() { @Override public void run() { //建立鏈接客戶端 connector = new NioSocketConnector(); //設置鏈接超時時間 connector.setConnectTimeoutMillis(30000); //添加過濾器 connector.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); //設置接收緩衝區大小 connector.getSessionConfig().setReadBufferSize(1024); //設置處理器 connector.setHandler(minaClientHandler); //設置默認方位地址 connector.setDefaultRemoteAddress(new InetSocketAddress(ConnectUtils.HOST,ConnectUtils.POST)); //添加劇連監聽 connector.addListener(new IoListener(){ @Override public void sessionDestroyed(IoSession ioSession) throws Exception { int count = 0; for(;;){ try { count++; ConnectFuture future = connector.connect(); future.awaitUninterruptibly();//等待鏈接建立完成 session = future.getSession();//獲取session if(session.isConnected()){ System.out.println("斷線了 可是又重連了"); count = 0; break; } }catch (Exception e){ if(count > ConnectUtils.IDLE_TIME){ break; }else { SystemClock.sleep(5000); } } } } }); for(;;){ try { ConnectFuture future = connector.connect(); future.awaitUninterruptibly(); System.out.println("socket 鏈接成功"); session = future.getSession(); session.write("start"); break; }catch (Exception e){ SystemClock.sleep(5000); } } } }).start(); } @Override public void onDestroy() { super.onDestroy(); connector.dispose(); } private class MinaClientHandler extends IoHandlerAdapter{ @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { super.exceptionCaught(session, cause); Log.d(TAG,"exceptionCaught--------" + cause); } @Override public void messageReceived(IoSession session, Object message) throws Exception { super.messageReceived(session, message); Log.d(TAG,"messageReceived---------" + message ); } @Override public void messageSent(IoSession session, Object message) throws Exception { super.messageSent(session, message); Log.d(TAG,"messageSent-------" + message); } @Override public void sessionClosed(IoSession session) throws Exception { super.sessionClosed(session); Log.d(TAG,"sessionClosed-------"); } @Override public void sessionCreated(IoSession session) throws Exception { super.sessionCreated(session); Log.d(TAG,"sessionCreated------" + session); } @Override public void sessionOpened(IoSession session) throws Exception { super.sessionOpened(session); Log.d(TAG,"sessionOpened---------"); } } /** * 建立一個監聽器實現mina的IoServiceListener接口,裏面的方法能夠不用實現 */ private class IoListener implements IoServiceListener{ @Override public void serviceActivated(IoService ioService) throws Exception { } @Override public void serviceIdle(IoService ioService, IdleStatus idleStatus) throws Exception { } @Override public void serviceDeactivated(IoService ioService) throws Exception { } @Override public void sessionCreated(IoSession ioSession) throws Exception { } @Override public void sessionClosed(IoSession ioSession) throws Exception { } @Override public void sessionDestroyed(IoSession ioSession) throws Exception { } } }
三.對於粘包的處理 是創建臨時緩衝區來處理this
public synchronized void Decode(char[] data) { for (int i = 0; i < data.length; i++) { char byt = data[i]; this.temp.add(byt); if (byt == '"') { if (!this.instring) { this.instring = true; } else if (getPrev() != '\\') { this.instring = false; } } if (instring) continue; if (byt == '}' || byt == ']') { end = true; left--; } if (byt == '{' || byt == '[') { left++; } if ((left) < 0) { temp.clear(); this.instring = false; this.left = 0; continue; } if (end && left == 0) { end = false; char[] p =new char[temp.size()]; // temp.toArray(p) ;//完整協議包 for(int j =0; j< temp.size();j++){ p[j] = temp.get(j); } // todo : log // if (OnPackageHanded != null) { // OnPackageHanded(package); // } if(this.HandledPackage.size()>100){ this.HandledPackage.poll(); } this.HandledPackage.offer(p); temp.clear(); this.instring = false; this.left = 0; continue; } } }