Socket for android 简单实例

最近在实现socket通信,所以写个demo来简单实现下。我用了一种是原始的socket实现,另一种是MINA框架来实现的。

下载demo:http://download.csdn.net/detail/qq_29774291/9826648

一.先看第一种方法

a)、创建Socket对象,指明需要连接的服务器的地址和端口。

b)、建立连接后,通过输出流向服务器发送请求信息。

c)、通过输入流获取服务器的响应信息。

d)、关闭响应资源

如下是主要代码

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框架实现的

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 {

        }
    }
}

三.对于粘包的处理  是建立临时缓冲区来处理

 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;
            }

        }
    }

 

posted @ 2017-04-26 17:31  王丰蛋哥  阅读(2052)  评论(0编辑  收藏  举报