您的位置:首页 > 移动开发 > Android开发

android进程间通信ipc Socket (二)

2017-10-28 21:40 337 查看
通过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


> 源码下载地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息