IPC 机制---使用Socket

时间:2021-04-02 16:14:10
IPC 机制---使用Socket

Socket 也称套接字 ,是网络通信中的概念,它分为流式套接字 和用户数据报套接字 两种

流式套接字 :对应于传输控制层的TCP协议 TCP协议 是面向连接的协议,提供稳定的双向通信功能,TCP的连接需要经过三次握手才能完成,为了提供稳定的数据传输功能,其本身提供了超时重传机制,因此具有很高的稳定性。
用户数据报套接字:对应于传输控制层的UDP协议,UDP是无连接的,提供不稳定的单向通信功能,当然UDP也可以实现双向通信功能。在性能上UDP具有更好的效率,其缺点是不能保证数据一定能够正确传输,尤其是在网络拥塞的情况下。
使用 Socket 来进行通信首先需要声明权限    <uses-permissionandroid:name="android.permission.INTERNET"/>    <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>

其次不能够在主线程中访问网络,因为这会导致我们的程序无法在Android4.0 以上的设备运行。而且进行网络操作很可能是耗时的,如果放在主线程的中,会影响程序的响应效率。

服务端代码: publicclassTCPServerServiceextendsService {
   privatebooleanmIsServiceDestoryed=false;   privateString[]mDefinedMessages=newString[] {           "浣犲ソ鍟婏紝鍝堝搱",           "璇烽棶浣犲彨浠�涔堝悕瀛楀憖锛�",           "浠婂ぉ鍖椾含澶╂皵涓嶉敊鍟婏紝shy",           "浣犵煡閬撳悧锛熸垜鍙槸鍙互鍜屽涓汉鍚屾椂鑱婂ぉ鐨勫摝",           "缁欎綘璁蹭釜绗戣瘽鍚э細鎹鐖辩瑧鐨勪汉杩愭皵涓嶄細澶樊锛屼笉鐭ラ亾鐪熷亣銆�"    };
   @Override   publicvoidonCreate() {       newThread(newTcpServer()).start();       super.onCreate();    }
   @Override   publicIBinder onBind(Intent intent) {       returnnull;    }
   @Override   publicvoidonDestroy() {       mIsServiceDestoryed=true;       super.onDestroy();    }
   privateclassTcpServerimplementsRunnable {
       @SuppressWarnings("resource")       @Override       publicvoidrun() {            ServerSocket serverSocket =null;           try{                serverSocket =newServerSocket(8688);            }catch(IOException e) {                System.err.println("establish tcp server failed, port:8688" );                e.printStackTrace();               return;            }
           while(!mIsServiceDestoryed) {               try{                   // 鎺ュ彈瀹㈡埛绔姹�                   finalSocket client = serverSocket.accept();                    System.out.println("accept");                   newThread() {                       @Override                       publicvoidrun() {                           try{                                responseClient(client);                            }catch(IOException e) {                                e.printStackTrace();                            }                        };                    }.start();
                }catch(IOException e) {                    e.printStackTrace();                }            }        }    }
   privatevoidresponseClient(Socket client)throwsIOException {       // 用于接收客户端消息        BufferedReader in =newBufferedReader(newInputStreamReader(                client.getInputStream()));       // 用于向客户端发送消息        PrintWriter out =newPrintWriter(newBufferedWriter(               newOutputStreamWriter(client.getOutputStream())),true);        out.println("娆㈣繋鏉ュ埌鑱婂ぉ瀹わ紒");       while(!mIsServiceDestoryed) {            String str = in.readLine();            System.out.println("msg from client:" + str);
           if(str ==null) {             //客户端断开连接                break;            }           inti =newRandom().nextInt(mDefinedMessages.length);            String msg =mDefinedMessages[i];            out.println(msg);            System.out.println("send :" + msg);        }        System.out.println("client quit." );       // 鍏抽棴娴�        MyUtils.close(out);        MyUtils.close(in);        client.close();    }
}
客户端代码: publicclassTCPClientActivityextendsActivityimplementsOnClickListener {
   privatestaticfinalintMESSAGE_RECEIVE_NEW_MSG= 1;   privatestaticfinalintMESSAGE_SOCKET_CONNECTED= 2;
   privateButtonmSendButton;   privateTextViewmMessageTextView;   privateEditTextmMessageEditText;
   privatePrintWritermPrintWriter;   privateSocketmClientSocket;
   @SuppressLint("HandlerLeak")   privateHandlermHandler=newHandler() {       @Override       publicvoidhandleMessage(Message msg) {           switch(msg.what) {           caseMESSAGE_RECEIVE_NEW_MSG: {               mMessageTextView.setText(mMessageTextView.getText()                        + (String) msg.obj);               break;            }           caseMESSAGE_SOCKET_CONNECTED: {               mSendButton.setEnabled(true);               break;            }           default:               break;            }        }    };
   @Override   protectedvoidonCreate(Bundle savedInstanceState) {       super.onCreate(savedInstanceState);        setContentView(R.layout.activity_tcpclient);       mMessageTextView= (TextView) findViewById(R.id.msg_container);       mSendButton= (Button) findViewById(R.id.send);       mSendButton.setOnClickListener(this);       mMessageEditText= (EditText) findViewById(R.id.msg);        Intent service =newIntent(this, TCPServerService.class);        startService(service);       newThread() {           @Override           publicvoidrun() {                connectTCPServer();            }        }.start();    }
   @Override   protectedvoidonDestroy() {       if(mClientSocket!=null) {           try{               mClientSocket.shutdownInput();               mClientSocket.close();            }catch(IOException e) {                e.printStackTrace();            }        }       super.onDestroy();    }
   @Override   publicvoidonClick(View v) {       if(v ==mSendButton) {           finalString msg =mMessageEditText.getText().toString();           if(!TextUtils.isEmpty(msg) &&mPrintWriter!=null) {               mPrintWriter.println(msg);               mMessageEditText.setText("");                String time = formatDateTime(System.currentTimeMillis());               finalString showedMsg ="self "+ time +":"+ msg +"\n";               mMessageTextView.setText(mMessageTextView.getText() + showedMsg);            }        }    }
   @SuppressLint("SimpleDateFormat")   privateString formatDateTime(longtime) {       returnnewSimpleDateFormat("(HH:mm:ss)").format(newDate(time));    }
   privatevoidconnectTCPServer() {        Socket socket =null;       while(socket ==null) {           try{                socket =newSocket("localhost", 8688);               mClientSocket= socket;               mPrintWriter=newPrintWriter(newBufferedWriter(                       newOutputStreamWriter(socket.getOutputStream())),true);               mHandler.sendEmptyMessage(MESSAGE_SOCKET_CONNECTED);                System.out.println("connect server success" );            }catch(IOException e) {                SystemClock.sleep(1000);                System.out.println("connect tcp server failed, retry..." );            }        }
       try{           // 鎺ユ敹鏈嶅姟鍣ㄧ鐨勬秷鎭�            BufferedReader br =newBufferedReader(newInputStreamReader(                    socket.getInputStream()));           while(!TCPClientActivity.this.isFinishing()) {                String msg = br.readLine();                System.out.println("receive :" + msg);               if(msg !=null) {                    String time = formatDateTime(System.currentTimeMillis());                   finalString showedMsg ="server "+ time +":"+ msg                            +"\n";                   mHandler.obtainMessage(MESSAGE_RECEIVE_NEW_MSG, showedMsg)                            .sendToTarget();                }            }            System.out.println("quit...");            MyUtils.close(mPrintWriter);            MyUtils.close(br);            socket.close();        }catch(IOException e) {            e.printStackTrace();        }    }
}