1.Socket简介

Socket也称作“套接字“,是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。它分为流式套接字和数据包套接字,分别对应网络传输控制层的TCP和UDP协议。TCP协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。它使用三次握手协议建立连接,并且提供了超时重传机制,具有很高的稳定性。UDP协议则是是一种无连接的协议,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多。 

从上图我们也可以看出,不同的用户进程通过Socket来进行通信,所以Socket也是一种IPC方式,接下来我们用TCP服务来实现一个简单的聊天程序。

2.实现聊天程序服务端

配置

首先我们来实现服务端,当然要使用Socket我们需要在AndroidManifest.xml声明如下的权限:

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

我们需要实现一个远程的Service来当作聊天程序的服务端,AndroidManifest.xml文件中配置service:

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

实现Service

接下来我们在Service启动时,在线程中建立TCP服务,我们监听的是8688端口,等待客户端连接,当客户端连接时就会生成Socket。通过每次创建的Socket就可以和不同的客户端通信了。当客户端断开连接时,服务端也会关闭Socket并结束结束通话线程。服务端首先会向客户端发送一条消息:“您好,我是服务端”,并接收客户端发来的消息,将收到的消息进行加工再返回给客户端。

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 {//监听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()));// 用于向客户端发送消息PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);out.println("您好,我是服务端");while (!isServiceDestroyed) {String str = in.readLine();Log.i("moon", "收到客户端发来的信息"   str);if (TextUtils.isEmpty(str)) {//客户端断开了连接Log.i("moon", "客户端断开连接");break;}String message = "收到了客户端的信息为:"   str;// 从客户端收到的消息加工再发送给客户端out.println(message);}out.close();in.close();client.close();}@Overridepublic void onDestroy() {isServiceDestroyed = true;super.onDestroy();}
}

3.实现聊天程序客户端

客户端Activity会在onCreate方法中启动服务端,并开启线程连接服务端Socket。为了确保能连接成功,采用了超时重连的策略,每次连接失败时都会重新建立连接。连接成功后,客户端会收到服务端发送的消息:“您好,我是服务端”,我们也可以在EditText输入字符并发送到服务端。

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();//向服务器发送信息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 {//选择和服务器相同的端口8688socket = new Socket("localhost", 8688);mClientSocket = socket;mPrintWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);} catch (IOException e) {SystemClock.sleep(1000);}}try {// 接收服务器端的消息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"   "服务端:"   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="向服务器发消息" /></LinearLayout>
</RelativeLayout>

4.运行聊天程序

运行程序,我们可以看到客户端和服务端是两个进程: 

客户端首先会收到服务端的信息:”您好,我是服务端”,接下来我们向服务端发送“我想要怒放的生命”。这时候服务端收到了这条信息并返回给客户端加工后的这条信息: 

  

  

https://github.com/henrymorgen/MoonSocket  

  

本文转载于:猿2048⇨https://www.mk2048.com/blog/blog.php?id=bbjckkj&title=Android IPC机制(五)用Socket实现跨进程聊天程序

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

  1. android跨进程关闭服务器,Android IPC机制(五)用Socket实现跨进程聊天程序

    本文首发于微信公众号「后厂技术官」 1.Socket简介 Socket也称作"套接字",是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层 ...

  2. android studio 跨进程,Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用...

    本文首发于微信公众号「后厂技术官」 在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法,但是我们能发现Messeng ...

  3. Android IPC机制(4)-Binder连接池

    本系列的所有文章: Android IPC机制(1)-序列化机制 Android IPC机制(2)-AIDL Android IPC机制(3)-Messenger Android IPC机制(4)-B ...

  4. (转)Android IPC机制详解

    o IBinder接口 IBinder接口是对跨进程的对象的抽象.普通对象在当前进程可以访问,如果希望对象能被其它进程访问,那就必须实现IBinder接口.IBinder接口可以指向本地对象,也可以指 ...

  5. Android IPC 机制详解:IBinder

    http://www.linuxgraphics.cn/android/ipc_ibinder.html IBinder 接口 IBinder接口是对跨进程的对象的抽象.普通对象在当前进程可以访问,如 ...

  6. Android IPC机制之IPC概念、Android 多进程和相关基础知识

    1.IPC 的基本概念 1.1 IPC的使用场景 IPC 即 Inter-Process Communication 进程间通信,IPC用于多进程,而Android的多进程情况一般有: 1.一个应用需 ...

  7. Android IPC机制

    #IPC简介 IPC是 Inter-Process Communication的缩写,含义为进程间的通信或者跨进程的通信,是指两个进程进行数据交换的过程, ###什么是线程? 线程是cpu调度的最小单 ...

  8. 【Java】Socket多客户端Client-Server聊天程序

    文章目录 任务要求 实现代码 工具类 服务器端线程 客户端线程 服务器端程序 客户端程序 运行说明 任务要求 编写一个简单的Socket多客户端聊天程序: 客户端程序,从控制台输入字符串,发送到服务器 ...

  9. android ipc简单理解,Android IPC 机制【1】--简介

    一.android 中进程间通信常用的有以下几种机制 ------------------------------------------------------------------------- ...

最新文章

  1. Android使用自定义View时:Error inflating class错误的原因。
  2. DLL load failed: The specified module could not be found
  3. 版本号比较函数-js
  4. 列表输出循环左移_互联网人工智能开发语言Python之for循环、break、continue详解...
  5. 汉字的ascii码值范围_ASCII代码
  6. 在GIS中运用坐标系统
  7. idea隐藏 .iml 和 .idea 等自动生成文件
  8. F5解决方案– 教育行业解决方案1(分析篇)
  9. iOS上架被拒理由及相关解决方案记录
  10. 怎样在spyder中暂停程序的运行
  11. 已知p是一个指向类a的数据成员m的指针_C++ this指针的理解和作用
  12. html5 苹果没有音乐播放器,GitHub - ksky521/player: html5版本音乐播放器,支持iOS设备...
  13. 网络安全——计算机网络拓扑图
  14. Button 点击没有反应
  15. 服务器ssh升级导致的java程序ssh连接失败
  16. 时间都去哪儿了,你又想让它去哪儿
  17. c语言sinf函数,sinf_数值 | Numerics_C_参考手册_非常教程
  18. Google电话面试的结果
  19. Lion的无线网络诊断工具
  20. Widows 注册表 HKEY_CLASSES_ROOT

热门文章

  1. Oracle启动操作
  2. 点分治经典_动态点分治
  3. CPU时间分片、多线程、并发和并行
  4. Eclipse新建java类的时候,自动创建注释
  5. 《中国文化要略》第八章 古代教育 第九章 科举制度
  6. Mono for android,Xamarin点击事件的多种写法
  7. java实现原数组根据下标分隔成两个子数组并且在原数组中交换两个子数组的位置...
  8. cocos2d-x for android配置 运行 Sample on Linux OS
  9. UVAlive 6131 dp+斜率优化
  10. ListView展示SIM信息