美文网首页
2.4 Android中的IPC方式(四)

2.4 Android中的IPC方式(四)

作者: 武安长空 | 来源:发表于2016-06-17 14:14 被阅读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();
        }
    }
    

    相关文章

      网友评论

          本文标题:2.4 Android中的IPC方式(四)

          本文链接:https://www.haomeiwen.com/subject/xndvdttx.html