日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android IPC机制(五)用Socket实现跨进程聊天程序

發(fā)布時間:2023/12/2 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android IPC机制(五)用Socket实现跨进程聊天程序 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.Socket簡介

Socket也稱作“套接字“,是在應(yīng)用層和傳輸層之間的一個抽象層,它把TCP/IP層復(fù)雜的操作抽象為幾個簡單的接口供應(yīng)用層調(diào)用以實現(xiàn)進程在網(wǎng)絡(luò)中通信。它分為流式套接字和數(shù)據(jù)包套接字,分別對應(yīng)網(wǎng)絡(luò)傳輸控制層的TCP和UDP協(xié)議。TCP協(xié)議是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。它使用三次握手協(xié)議建立連接,并且提供了超時重傳機制,具有很高的穩(wěn)定性。UDP協(xié)議則是是一種無連接的協(xié)議,且不對傳送數(shù)據(jù)包進行可靠性保證,適合于一次傳輸少量數(shù)據(jù),UDP傳輸?shù)目煽啃杂蓱?yīng)用層負責。在網(wǎng)絡(luò)質(zhì)量令人十分不滿意的環(huán)境下,UDP協(xié)議數(shù)據(jù)包丟失會比較嚴重。但是由于UDP的特性:它不屬于連接型協(xié)議,因而具有資源消耗小,處理速度快的優(yōu)點,所以通常音頻、視頻和普通數(shù)據(jù)在傳送時使用UDP較多。?

從上圖我們也可以看出,不同的用戶進程通過Socket來進行通信,所以Socket也是一種IPC方式,接下來我們用TCP服務(wù)來實現(xiàn)一個簡單的聊天程序。

2.實現(xiàn)聊天程序服務(wù)端

配置

首先我們來實現(xiàn)服務(wù)端,當然要使用Socket我們需要在AndroidManifest.xml聲明如下的權(quán)限:

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

我們需要實現(xiàn)一個遠程的Service來當作聊天程序的服務(wù)端,AndroidManifest.xml文件中配置service:

<serviceandroid:name=".SocketServerService"android:process=":remote" />

實現(xiàn)Service

接下來我們在Service啟動時,在線程中建立TCP服務(wù),我們監(jiān)聽的是8688端口,等待客戶端連接,當客戶端連接時就會生成Socket。通過每次創(chuàng)建的Socket就可以和不同的客戶端通信了。當客戶端斷開連接時,服務(wù)端也會關(guān)閉Socket并結(jié)束結(jié)束通話線程。服務(wù)端首先會向客戶端發(fā)送一條消息:“您好,我是服務(wù)端”,并接收客戶端發(fā)來的消息,將收到的消息進行加工再返回給客戶端。

package com.example.liuwangshu.moonsocket; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.text.TextUtils; import android.util.Log; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket;public class SocketServerService extends Service {private boolean isServiceDestroyed = false;@Overridepublic void onCreate() {new Thread(new TcpServer()).start();super.onCreate();}@Overridepublic IBinder onBind(Intent intent) {// TODO: Return the communication channel to the service.throw new UnsupportedOperationException("Not yet implemented");}private class TcpServer implements Runnable {@Overridepublic void run() {ServerSocket serverSocket;try {//監(jiān)聽8688端口serverSocket = new ServerSocket(8688);} catch (IOException e) {return;}while (!isServiceDestroyed) {try {// 接受客戶端請求,并且阻塞直到接收到消息final Socket client = serverSocket.accept();new Thread() {@Overridepublic 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()));// 用于向客戶端發(fā)送消息PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);out.println("您好,我是服務(wù)端");while (!isServiceDestroyed) {String str = in.readLine();Log.i("moon", "收到客戶端發(fā)來的信息" str);if (TextUtils.isEmpty(str)) {//客戶端斷開了連接Log.i("moon", "客戶端斷開連接");break;}String message = "收到了客戶端的信息為:" str;// 從客戶端收到的消息加工再發(fā)送給客戶端out.println(message);}out.close();in.close();client.close();}@Overridepublic void onDestroy() {isServiceDestroyed = true;super.onDestroy();} }

3.實現(xiàn)聊天程序客戶端

客戶端Activity會在onCreate方法中啟動服務(wù)端,并開啟線程連接服務(wù)端Socket。為了確保能連接成功,采用了超時重連的策略,每次連接失敗時都會重新建立連接。連接成功后,客戶端會收到服務(wù)端發(fā)送的消息:“您好,我是服務(wù)端”,我們也可以在EditText輸入字符并發(fā)送到服務(wù)端。

package com.example.liuwangshu.moonsocket;import android.content.Intent; import android.os.SystemClock; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket;public class SocketClientActivity extends AppCompatActivity {private Button bt_send;private EditText et_receive;private Socket mClientSocket;private PrintWriter mPrintWriter;private TextView tv_message;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_socket);initView();Intent service = new Intent(this, SocketServerService.class);startService(service);new Thread() {@Overridepublic void run() {connectSocketServer();}}.start();}private void initView() {et_receive= (EditText) findViewById(R.id.et_receive);bt_send= (Button) findViewById(R.id.bt_send);tv_message= (TextView) this.findViewById(R.id.tv_message);bt_send.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {final String msg = et_receive.getText().toString();//向服務(wù)器發(fā)送信息if(!TextUtils.isEmpty(msg)&&null!=mPrintWriter) {mPrintWriter.println(msg);tv_message.setText(tv_message.getText() "\n" "客戶端:" msg);et_receive.setText("");}}});}private void connectSocketServer() {Socket socket = null;while (socket == null) {try {//選擇和服務(wù)器相同的端口8688socket = new Socket("localhost", 8688);mClientSocket = socket;mPrintWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);} catch (IOException e) {SystemClock.sleep(1000);}}try {// 接收服務(wù)器端的消息BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));while (!isFinishing()) {final String msg = br.readLine();if (msg != null) {runOnUiThread(new Runnable() {@Overridepublic void run() {tv_message.setText(tv_message.getText() "\n" "服務(wù)端:" msg);}});}}mPrintWriter.close();br.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}

布局很簡單(activity_socket.xml):

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@ id/tv_message"android:layout_width="match_parent"android:layout_height="400dp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="50dp"android:layout_alignParentBottom="true"android:orientation="horizontal"><EditTextandroid:id="@ id/et_receive"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="2"/><Buttonandroid:id="@ id/bt_send"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:text="向服務(wù)器發(fā)消息" /></LinearLayout> </RelativeLayout>

4.運行聊天程序

運行程序,我們可以看到客戶端和服務(wù)端是兩個進程:?

客戶端首先會收到服務(wù)端的信息:”您好,我是服務(wù)端”,接下來我們向服務(wù)端發(fā)送“我想要怒放的生命”。這時候服務(wù)端收到了這條信息并返回給客戶端加工后的這條信息:?

  

  

https://github.com/henrymorgen/MoonSocket  

  

本文轉(zhuǎn)載于:猿2048?https://www.mk2048.com/blog/blog.php?id=bbjckkj&title=Android IPC機制(五)用Socket實現(xiàn)跨進程聊天程序

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的Android IPC机制(五)用Socket实现跨进程聊天程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。