android进程间通信ipc Socket (二)

来源:互联网 发布:汶川地震多严重知乎 编辑:程序博客网 时间:2024/05/20 09:44

通过Socket通信有两种方式:

流式套接字(TCP)
用户数据报套接字(UDP)

下面介绍 流式套接字(TCP)方式通信

这里写图片描述

显示的log是服务器端打印的日志 接收客户端的消息

服务端代码

package com.example.socketdemo;import android.app.Service;import android.content.Intent;import android.os.IBinder;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;import java.net.SocketException;/** * Created by yw on 2017/10/28. */public class TPCSocket extends Service {    private boolean mIsServiceDestoryed = false;    @Override    public void onCreate() {        //监听连接的状态        new TcpThread().start();        super.onCreate();    }    @Override    public IBinder onBind(Intent intent) {        return null;    }    @Override    public void onDestroy() {        mIsServiceDestoryed = true;        super.onDestroy();    }    private class TcpThread extends Thread {        @Override        public void run() {            ServerSocket serverSocket = null;            try {                serverSocket = new ServerSocket(8888);            } catch (IOException e) {                e.printStackTrace();                return;            }            //接受客户端的请求            try {                final Socket socket = serverSocket.accept();                //回应客户端                new Thread() {                    @Override                    public void run() {                        try {                            handleMsg(socket);                        } catch (Exception e) {                            e.printStackTrace();                        }                    }                }.start();            } catch (Exception e) {                e.printStackTrace();            }        }    }    private void handleMsg(Socket socket) throws Exception{            //发送消息        PrintWriter out = new PrintWriter(                    new BufferedWriter(new                            OutputStreamWriter(socket.getOutputStream())), true);//        BufferedWriter o = new BufferedWriter(new//                OutputStreamWriter(socket.getOutputStream()));//        o.write("jfdk");        //OutputStreamWriter(socket.getOutputStream()))  字符流通向字节流            //接受消息        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));        //InputStreamReader(socket.getInputStream())  字节流通向字符流        out.println("来聊天啊");        //在服务没有销毁的时候 一直循环处理消息        while (!mIsServiceDestoryed) {           try {               String msg = in.readLine();               if (msg == null) {                   //客户端断开了                   break;               }               Log.d("yw", msg);               //给客户端回消息               out.println("服务器发来的消息");           } catch (SocketException e) {               Log.d("yw", e.getMessage());               break;           }        }        //关闭资源        out.close();        in.close();        socket.close();    }}

总要逻辑

服务启动的时候,开个线程
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
监听8888端口,等待客户端的连接;

注册服务
其他的进程名命名方法

<service android:name=".TPCSocket"            android:process=":tpc" />

客户端代码

package com.example.socketdemo;import android.app.ProgressDialog;import android.content.Intent;import android.os.Handler;import android.os.Message;import android.os.SystemClock;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;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 MainActivity extends AppCompatActivity {    private TextView mMsgList;    private EditText mEt;    private boolean mIsConn = false;    private Socket mSocket = null;    private PrintWriter mPrintWriter;    private ProgressDialog mDialog;    private Thread mThread;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mMsgList = (TextView) findViewById(R.id.tv_msg_list);        mEt = (EditText) findViewById(R.id.et);        Intent intent = new Intent(this, TPCSocket.class);        startService(intent);    }    private class MyThread extends Thread {        @Override        public void run() {            while (mSocket == null) {                try {                    mSocket = new Socket("127.0.0.1", 8888);                    mIsConn = true;                    //发送的对象                    mPrintWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream())), true);                } catch (IOException e) {                    mIsConn = false;                    e.printStackTrace();                    SystemClock.sleep(1000); //重试时间间隔1秒                }            }            //发送连接成功消息            mHandler.sendEmptyMessage(1);            //接受消息            while (mIsConn && !mSocket.isClosed()) {                try {                    BufferedReader reader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));                    String msg = reader.readLine();                    Log.d("yw", msg);                    Message message = new Message();                    Bundle bundle = new Bundle();                    bundle.putString("msg", msg);                    message.setData(bundle);                    message.what = 2;                    mHandler.sendMessage(message);                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    public void connService(View view) {        if (mIsConn) {            Toast.makeText(this, "不要重复连接哦", Toast.LENGTH_SHORT).show();            return;        }        //连接服务        mDialog =                new ProgressDialog(this);        mDialog.setCancelable(false);        mDialog.show();        mThread = new MyThread();        mThread.start();    }    public void disService(View view) {        if (!mIsConn) {            Toast.makeText(this, "不要重复断开哦", Toast.LENGTH_SHORT).show();            return;        }        //断开服务        try {            mThread.interrupt();            mSocket.close();            mSocket = null;            mIsConn = false;        } catch (IOException e) {            e.printStackTrace();        }    }    public void sendMsg(View view) {        if (!mIsConn) {            Toast.makeText(this, "连接服务后才能发送哦", Toast.LENGTH_SHORT).show();            return;        }        //发送消息        new Thread() {            @Override            public void run() {                mPrintWriter.println(mEt.getText().toString());            }        }.start();    }    private Handler mHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case 1:                    //连接成功                    mDialog.dismiss();                    Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show();                    break;                case 2:                    //显示消息                    String message = msg.getData().getString("msg");                    mMsgList.setText(mMsgList.getText() + "\n" + message);                    break;            }            super.handleMessage(msg);        }    };}

总要逻辑

开个线程连接服务器,连接成功之后,通过Handler通知ui主线程,然后ui线程会提示用户连接成功。连接成功,socket不为空,同时会一直监听服务器发来的消息,一旦有消息,通过Handler通知ui主线程更新界面。

view界面代码

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:orientation="vertical"    android:layout_height="match_parent" tools:context="com.example.socketdemo.MainActivity">    <Button        android:text="连接"        android:onClick="connService"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <Button        android:text="断开"        android:onClick="disService"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <Button        android:onClick="sendMsg"        android:text="发消息"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <EditText        android:id="@+id/et"        android:layout_marginBottom="10dp"        android:layout_width="match_parent"        android:layout_height="wrap_content" />    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"        android:text="消息列表:\n" />    <TextView        android:id="@+id/tv_msg_list"        android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
**最后加上权限**
<uses-permission android:name="android.permission.INTERNET" />

不然会报异常:

java.net.SocketException: Permission denied

> 源码下载地址

原创粉丝点击