美文网首页
IPC之基于TCP协议的Socket的使用

IPC之基于TCP协议的Socket的使用

作者: chenmingzhi | 来源:发表于2016-10-22 23:08 被阅读0次

    Socket也称为套接字,可以用来实现进程间的通信。Socket本身支持传输任意字节流。

    demo实现了简单的跨进程的聊天程序。

    声明权限

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    

    服务端

    public class TCPServerService extends Service {
    
        private boolean mIsServiceDestoryed = false;
    
        private String[] mDefinedMessages = new String[]{
                "你好啊~~",
                "我叫TCP,你呢",
                "今天刮台风了,OMG",
                "我是人工智能(障)噢",
        };
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            new Thread(new TcpServer()).start();
            super.onCreate();
        }
    
        @Override
        public void onDestroy() {
            mIsServiceDestoryed = true;
            super.onDestroy();
        }
    
        private class TcpServer implements Runnable{
    
            @SuppressWarnings("resource")
            @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();
                }
                while (!mIsServiceDestoryed){
                    try {
                        final Socket client = serverSocket.accept();//接收客户端的数据
                        System.out.println("accept");
                        new Thread(){
                            @Override
                            public void run() {
                                try {
                                    responseClient(client);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }.start();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        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();//接收到的来自客户端的消息
                System.out.println("msg from client:" + str);
                if(str ==null){
                    break;//断开连接
                }
                int i = new Random().nextInt(mDefinedMessages.length);
                String msg = mDefinedMessages[i];
                out.println(msg);
                System.out.println("send:" + msg);
            }
            System.out.println("client quit.:");
            //关闭流
            out.close();
            in.close();
            client.close();
        }
    }
    

    客户端

    public class MainActivity 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;
    
        @SuppressLint("HandlerLeak")
        private Handler mHandler = new Handler(){
            @Override@SuppressLint("HandlerLeak")
            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;
                    default:
                        break;
                }
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView(){
            mMessageTextView = (TextView) findViewById(R.id.textView);
            mSendButton = (Button) findViewById(R.id.button);
            mSendButton.setOnClickListener(this);
            mMessageEditText = (EditText) findViewById(R.id.editText);
            Intent service = new Intent(this, TCPServerService.class);
            startService(service);
            new Thread(){
                @Override
                public void run() {
                    connectTCPServer();
                }
            }.start();
        }
    
        @Override
        protected void onDestroy() {
            //Activity退出时,关闭当前的Socket
            if(mClientSocket != null){
                try {
                    mClientSocket.shutdownInput();
                    mClientSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            super.onDestroy();
        }
    
        @Override
        public void onClick(View v) {
            if(v.getId() ==R.id.button){
                final String msg = mMessageEditText.getText().toString();
                if(!TextUtils.isEmpty(msg) && mPrintWriter != null){//isEmpty() null或""都返回true
                    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);//指定服务器端的ip地址和端口号
                    mClientSocket = socket;
                    mPrintWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
                    mHandler.sendEmptyMessage(MESSAGE_SOCKET_CONNECTED);
                    System.out.println("connect server success");
                } catch (IOException e) {
                    SystemClock.sleep(1000);//延迟一秒后重连
                    e.printStackTrace();
                }
            }
    
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                while (!MainActivity.this.isFinishing()){
                    String msg = br.readLine();
                    System.out.println("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();
                    }
                }
                System.out.println("quit...");
                mPrintWriter.close();
                br.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    }
    

    相关文章

      网友评论

          本文标题:IPC之基于TCP协议的Socket的使用

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