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(); } }
}
相关文章
- Qt信号槽机制的实现(面试的感悟,猜测每一个类保存的一个信号和槽的二维表,实际使用函数指针 元对象 还有类型安全的检查设定等等)
- Java中使用Lock简化同步机制
- Android:使用Socket网络通信时异常:: socket closed
- C#中的WinForm的消息机制简述,及消息机制下Invoke,和BeginInvoke的使用和区别
- socket 错误之:OSError: [WinError 10057] 由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。...
- 使用PHP Socket 编程模拟Http post和get请求
- socket长连接、短连接以及心跳包机制
- 使用 Socket 通信实现 FTP 客户端程序(一)
- TSL 和 SSL 是什么?它们有何关系?-定义:SSL(安全套接层)是一种早期的加密协议,用于在互联网通信中保障数据传输的安全性。它通过加密和身份验证机制,确保客户端(如浏览器)与服务器之间的通信不被窃听或篡改。 版本:SSL 1.0(未发布)、SSL 2.0(1995年,已废弃)、SSL 3.0(1996年,已淘汰)。 问题:SSL 3.0 及早期版本存在严重安全漏洞(如 POODLE 攻击),目前已被现代系统禁用。 2. TLS(Transport Layer Security) 定义:TLS(传输层安全协议)是 SSL 的继任者,旨在提供更安全的通信协议。TLS 由国际互联网工程任务组(IETF)标准化,逐步替代了 SSL。 版本:TLS 1.0(1999年,已淘汰)、TLS 1.1(2006年,已淘汰)、TLS 1.2(2008年,广泛使用)、TLS 1.3(2018年,最新标准)。 优势:更强的加密算法(如 AES、ChaCha20)、更高效的握手过程、支持前向保密(Perfect Forward Secrecy)等。 SSL 与 TLS 的关系 继承关系 TLS 直接基于 SSL 3.0 设计,可以视为 SSL 的升级版。TLS 1.0 最初命名为 SSL 3.1,后因标准化需要更名为 TLS。 协议兼容性
- 多进程环境中,使用multiprocessing.Manager 的代理机制(proxy)管理共享对象时,对象在不同进程中的引用可能不一致问题