2.4 Android中的IPC方式(四)

2016-06-17  本文已影响22人  武安长空

1. Socket简介

Socket也称为套接字,是网络通信中的概念。它分为流式套接字和用户数据报套接字,分别对应网络传输控制层的TCP和UDP协议。
TCP协议是面向连接的协议,提供稳定的双向通信功能,TCP的建立需要经过三次握手才能完成,为了提供稳定的数据传输功能,其本身提供了超时重传机制。
UDP是无连接的,提供不稳定的单项通信功能。在性能上具有更好的效率,其缺点是无法保证数据一定能够正确传输。

2. 外进程服务端的实现

public class SocketService extends Service {

    private boolean mIsServiceDestoryed = false;
    private String[] mDefinedMessages = new String[] {
            "你好啊,哈哈",
            "请问你叫什么名字呀?",
            "今天北京天气不错啊,shy",
            "你知道吗?我可是可以和多个人同时聊天的哦",
            "给你讲个笑话吧:据说爱笑的人运气不会太差,不知道真假。"
    };

    @Override
    public void onCreate() {
        new Thread(new TcpServer()).start();
        super.onCreate();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        mIsServiceDestoryed = true;
        super.onDestroy();
    }

    private class TcpServer implements Runnable {

        @Override
        public void run() {
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(8688);
            } catch (IOException e) {
                System.err.println("establish tcp server failed, port:8688");
                e.printStackTrace();
                return;
            }

            while (!mIsServiceDestoryed) {
                // 接受客户端请求
                final Socket client = serverSocket.accept();
                Log.e("aaa","accept");
                new Thread() {
                    @Override
                    public void run() {
                        responseClient(client);
                    };
                }.start();
            }
        }
    }

    private void responseClient(Socket client) throws IOException {
        // 用于接收客户端消息
        BufferedReader in = new BufferedReader(new InputStreamReader(
                client.getInputStream()));
        // 用于向客户端发送消息
        PrintWriter out = new PrintWriter(new BufferedWriter(
                new OutputStreamWriter(client.getOutputStream())), true);
        out.println("欢迎来到聊天室!");
        while (!mIsServiceDestoryed) {
            String str = in.readLine();
            Log.e("aaa","msg from client:" + str);
            if (str == null) {
                break;
            }
            int i = new Random().nextInt(mDefinedMessages.length);
            String msg = mDefinedMessages[i];
            out.println(msg);
            Log.e("aaa","send :" + msg);
        }
        Log.e("aaa","client quit.");
        // 关闭流
        in.close();
        out.close();
        client.close();
    }
}

3. 客户端实现

public class SocketActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int MESSAGE_RECEIVE_NEW_MSG = 1;
    private static final int MESSAGE_SOCKET_CONNECTED = 2;

    private Button mSendButton;
    private TextView mMessageTextView;
    private EditText mMessageEditText;

    private PrintWriter mPrintWriter;
    private Socket mClientSocket;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_RECEIVE_NEW_MSG: {
                    mMessageTextView.setText(mMessageTextView.getText()
                            + (String) msg.obj);
                    break;
                }
                case MESSAGE_SOCKET_CONNECTED: {
                    mSendButton.setEnabled(true);
                    break;
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_socket);
        mMessageTextView = (TextView) findViewById(R.id.msg_container);
        mSendButton = (Button) findViewById(R.id.send);
        mSendButton.setOnClickListener(this);
        mMessageEditText = (EditText) findViewById(R.id.msg);
        Intent service = new Intent(this, SocketService.class);
        startService(service);
        new Thread() {
            @Override
            public void run() {
                connectTCPServer();
            }
        }.start();
    }

    @Override
    protected void onDestroy() {
        if (mClientSocket != null) {
            mClientSocket.shutdownInput();
            mClientSocket.close();
        }
        super.onDestroy();
    }

    @Override
    public void onClick(View v) {
        if (v == mSendButton) {
            final String msg = mMessageEditText.getText().toString();
            if (!TextUtils.isEmpty(msg) && mPrintWriter != null) {
                mPrintWriter.println(msg);
                mMessageEditText.setText("");
                String time = formatDateTime(System.currentTimeMillis());
                final String showedMsg = "self " + time + ":" + msg + "\n";
                mMessageTextView.setText(mMessageTextView.getText() + showedMsg);
            }
        }
    }

    private String formatDateTime(long time) {
        return new SimpleDateFormat("(HH:mm:ss)").format(new Date(time));
    }

    private void connectTCPServer() {
        Socket socket = null;
        while (socket == null) {
            try {
                socket = new Socket("localhost", 8688);
                mClientSocket = socket;
                mPrintWriter = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())), true);
                mHandler.sendEmptyMessage(MESSAGE_SOCKET_CONNECTED);
                Log.e("aaa", "connect server success");
            } catch (IOException e) {
                SystemClock.sleep(1000);
                Log.e("aaa", "connect tcp server failed, retry...");
            }
        }

        // 接收服务器端的消息
        BufferedReader br = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));
        while (!SocketActivity.this.isFinishing()) {
            String msg = br.readLine();
            Log.e("aaa", "receive :" + msg);
            if (msg != null) {
                String time = formatDateTime(System.currentTimeMillis());
                final String showedMsg = "server " + time + ":" + msg
                        + "\n";
                mHandler.obtainMessage(MESSAGE_RECEIVE_NEW_MSG, showedMsg)
                        .sendToTarget();
            }
        }
        Log.e("aaa", "quit...");
        mPrintWriter.close();
        br.close();
        socket.close();
    }
}
上一篇下一篇

猜你喜欢

热点阅读