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(); } }
}
相关文章
- PyTorch 之 简介、相关软件框架、基本使用方法、tensor 的几种形状和 autograd 机制
- 黑马程序员_温习 网络编辑一 (个人笔记)摘要(网络概述---网络参考模型---网络传输要素---IP地址---端口----传输协议(UDP -- TCP)---Socket机制 )
- 自建Socket转发,使用远程桌面(mstsc)连接家中电脑
- pycharm软件的基本使用、python的注释语法、变量与常量、变量的命名风格、垃圾回收机制、数据类型、数据类型之整型、数据类型之浮点型
- 使用socket编程实现一个简单的文件服务器
- 黑马程序员——Map接口的使用,泛型机制,集合框架工具类Collections的使用
- 如何使用socket.io-stream上传文件?
- 使用raspberry pi和windows通过Cocket中的Socket发送图像(JPG)
- socket IPC(本地套接字 domain)
- socket(套接字)初使用