Android通过Socket与服务器之间进行通信的示例
时间:2022-07-28
本文章向大家介绍Android通过Socket与服务器之间进行通信的示例,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、首先进行Server的编写:
public class SocketServer {
private static Socket mSocket;
public static void main(String[] argc) {
try {
//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
ServerSocket serverSocket = new ServerSocket(12345);
InetAddress address = InetAddress.getLocalHost();
String ip = address.getHostAddress();
//2.调用accept()等待客户端连接
System.out.println("~~~服务端已就绪,等待客户端接入~,服务端ip地址: " + ip);
mSocket = serverSocket.accept();
//3.连接后获取输入流,读取客户端信息
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
is = mSocket.getInputStream();
isr = new InputStreamReader(is, "UTF-8");
br = new BufferedReader(isr);
String info = null;
while ((info = br.readLine()) != null) {
System.out.println("客户端发送过来的信息" + info);
if (info.equals(BackService.HEART_BEAT_STRING)) {
sendmsg("ok");
} else {
sendmsg("服务器发送过来的信息" + info);
}
}
mSocket.shutdownInput();
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//为连接上服务端的每个客户端发送信息
public static void sendmsg(String msg) {
PrintWriter pout = null;
try {
pout = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(mSocket.getOutputStream(), "UTF-8")), true);
pout.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、对客户端的编写,主要用用AIDL进行Server和Client
AIDL 的编写主要为以下三部分:
1、创建 AIDL
1)、创建要操作的实体类,实现 Parcelable 接口,以便序列化/反序列化 2)、新建 aidl 文件夹,在其中创建接口 aidl 文件以及实体类的映射 aidl 文件 3)、Make project ,生成 Binder 的 Java 文件
2、服务端
1)、创建 Service,在其中创建上面生成的 Binder 对象实例,实现接口定义的方法 2)、在 onBind() 中返回
3、客户端
1)、实现 ServiceConnection 接口,在其中拿到 AIDL 类 2)、bindService() 3)、调用 AIDL 类中定义好的操作请求
IBackService.aidl 文件
package com.example.dell.aidlservice;
// Declare any non-default types here with import statements
interface IBackService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
boolean sendMessage(String message);
}
Service的编写,命名为BackService
public class BackService extends Service {
private static final String TAG = "danxx";
public static final String HEART_BEAT_STRING = "HeartBeat";//心跳包内容
/**
* 心跳频率
*/
private static final long HEART_BEAT_RATE = 3 * 1000;
/**
* 服务器ip地址
*/
public static final String HOST = "172.16.50.115";
/**
* 服务器端口号
*/
public static final int PORT = 12345;
/**
* 服务器消息回复广播
*/
public static final String MESSAGE_ACTION = "message_ACTION";
/**
* 服务器心跳回复广播
*/
public static final String HEART_BEAT_ACTION = "heart_beat_ACTION";
/**
* 读线程
*/
private ReadThread mReadThread;
private LocalBroadcastManager mLocalBroadcastManager;
/***/
private WeakReference<Socket mSocket;
// For heart Beat
private Handler mHandler = new Handler();
/**
* 心跳任务,不断重复调用自己
*/
private Runnable heartBeatRunnable = new Runnable() {
@Override
public void run() {
if (System.currentTimeMillis() - sendTime = HEART_BEAT_RATE) {
boolean isSuccess = sendMsg(HEART_BEAT_STRING);//就发送一个rn过去 如果发送失败,就重新初始化一个socket
if (!isSuccess) {
mHandler.removeCallbacks(heartBeatRunnable);
mReadThread.release();
releaseLastSocket(mSocket);
new InitSocketThread().start();
}
}
mHandler.postDelayed(this, HEART_BEAT_RATE);
}
};
private long sendTime = 0L;
/**
* aidl通讯回调
*/
private IBackService.Stub iBackService = new IBackService.Stub() {
/**
* 收到内容发送消息
* @param message 需要发送到服务器的消息
* @return
* @throws RemoteException
*/
@Override
public boolean sendMessage(String message) throws RemoteException {
return sendMsg(message);
}
};
@Override
public IBinder onBind(Intent arg0) {
return iBackService;
}
@Override
public void onCreate() {
super.onCreate();
new InitSocketThread().start();
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
}
public boolean sendMsg(final String msg) {
if (null == mSocket || null == mSocket.get()) {
return false;
}
final Socket soc = mSocket.get();
if (!soc.isClosed() && !soc.isOutputShutdown()) {
new Thread(new Runnable() {
@Override
public void run() {
try {
OutputStream os = soc.getOutputStream();
String message = msg + "rn";
os.write(message.getBytes());
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
sendTime = System.currentTimeMillis();//每次发送成数据,就改一下最后成功发送的时间,节省心跳间隔时间
} else {
return false;
}
return true;
}
private void initSocket() {//初始化Socket
try {
//1.创建客户端Socket,指定服务器地址和端口
Socket so = new Socket(HOST, PORT);
mSocket = new WeakReference<Socket (so);
mReadThread = new ReadThread(so);
mReadThread.start();
mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//初始化成功后,就准备发送心跳包
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 心跳机制判断出socket已经断开后,就销毁连接方便重新创建连接
*
* @param mSocket
*/
private void releaseLastSocket(WeakReference<Socket mSocket) {
try {
if (null != mSocket) {
Socket sk = mSocket.get();
if (!sk.isClosed()) {
sk.close();
}
sk = null;
mSocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
class InitSocketThread extends Thread {
@Override
public void run() {
super.run();
initSocket();
}
}
// Thread to read content from Socket
class ReadThread extends Thread {
private WeakReference<Socket mWeakSocket;
private boolean isStart = true;
public ReadThread(Socket socket) {
mWeakSocket = new WeakReference<Socket (socket);
}
public void release() {
isStart = false;
releaseLastSocket(mWeakSocket);
}
@Override
public void run() {
super.run();
Socket socket = mWeakSocket.get();
if (null != socket) {
try {
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024 * 4];
int length = 0;
while (!socket.isClosed() && !socket.isInputShutdown() && isStart && ((length = is.read(buffer)) != -1)) {
if (length 0) {
String message = new String(Arrays.copyOf(buffer, length)).trim();
Log.e(TAG, message);
//收到服务器过来的消息,就通过Broadcast发送出去
if (message.equals("ok")) {//处理心跳回复
Intent intent = new Intent(HEART_BEAT_ACTION);
mLocalBroadcastManager.sendBroadcast(intent);
} else {
//其他消息回复
Intent intent = new Intent(MESSAGE_ACTION);
intent.putExtra("message", message);
mLocalBroadcastManager.sendBroadcast(intent);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(heartBeatRunnable);
mReadThread.release();
releaseLastSocket(mSocket);
}
}
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mResultText;
private EditText mEditText;
private Intent mServiceIntent;
private IBackService iBackService;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
iBackService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iBackService = IBackService.Stub.asInterface(service);
}
};
class MessageBackReciver extends BroadcastReceiver {
private WeakReference<TextView textView;
public MessageBackReciver(TextView tv) {
textView = new WeakReference<TextView (tv);
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
TextView tv = textView.get();
if (action.equals(BackService.HEART_BEAT_ACTION)) {
if (null != tv) {
Log.i("danxx", "Get a heart heat");
tv.setText("Get a heart heat");
}
} else {
Log.i("danxx", "Get a heart heat");
String message = intent.getStringExtra("message");
tv.setText("服务器消息:" + message);
}
}
}
private MessageBackReciver mReciver;
private IntentFilter mIntentFilter;
private LocalBroadcastManager mLocalBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
mResultText = (TextView) findViewById(R.id.resule_text);
mEditText = (EditText) findViewById(R.id.content_edit);
findViewById(R.id.send).setOnClickListener(this);
findViewById(R.id.send1).setOnClickListener(this);
mReciver = new MessageBackReciver(mResultText);
mServiceIntent = new Intent(this, BackService.class);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(BackService.HEART_BEAT_ACTION);
mIntentFilter.addAction(BackService.MESSAGE_ACTION);
}
@Override
protected void onStart() {
super.onStart();
mLocalBroadcastManager.registerReceiver(mReciver, mIntentFilter);
bindService(mServiceIntent, conn, BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
unbindService(conn);
mLocalBroadcastManager.unregisterReceiver(mReciver);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.send:
String content = mEditText.getText().toString();
try {
boolean isSend = iBackService.sendMessage(content);//Send Content by socket
Toast.makeText(this, isSend ? "success" : "fail", Toast.LENGTH_SHORT).show();
mEditText.setText("");
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.send1:
new Thread(new Runnable() {
@Override
public void run() {
try {
acceptServer();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
break;
default:
break;
}
}
private void acceptServer() throws IOException {
//1.创建客户端Socket,指定服务器地址和端口
Socket socket = new Socket("172.16.50.115", 12345);
//2.获取输出流,向服务器端发送信息
OutputStream os = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(os); //将输出流包装为打印流
//获取客户端的IP地址
InetAddress address = InetAddress.getLocalHost();
String ip = address.getHostAddress();
printWriter.write("客户端:~" + ip + "~ 接入服务器!!");
printWriter.flush();
socket.shutdownInput();
socket.close();
}
}
源码地址
以上就是本文的全部内容,希望对大家的学习有所帮助。
- Silverlight单元测试框架
- Enterprise Library深入解析与灵活应用(2): 通过SqlDependency实现Cache和Database的同步
- 让你感觉不真实的13个伟大科学成就和发现
- 分析Silverlight跨域调用
- Spring集成RabbiMQ-Spring AMQP新特性
- Nodejs学习笔记(二)--- 事件模块
- 巧用FireFox来调试Silverlight
- Nodejs学习笔记(一)--- 简介及安装Node.js开发环境
- WCF后续之旅(7):通过WCF Extension实现和Enterprise Library Unity Container的集成
- 区块链技术(一):Truffle开发入门
- Nodejs学习笔记(一)——初识Nodejs
- RabbitMQ入门-Topic模式
- 单分子数据储存取得一大突破,一枚“硬币”存量相当于100部iPhone 7
- Windows 7 旗舰版 VHD安装体验
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android如何自定义EditText光标与下划线颜色详解
- 基于Centos7 部署Varnish缓存代理服务器
- Android getActivity()为空的问题解决办法
- Android Notification使用方法总结
- Linux下redis的持久化、主从同步与哨兵详解
- 详解Android(共享元素)转场动画开发实践
- Android自定义View中attrs.xml的实例详解
- Android开发之缓冲dialog对话框创建、使用与封装操作
- Windows 10 下安装 Apache 2.4.41的教程
- Android基础教程数据存储之文件存储
- 关于Android短信验证码的获取的示例
- Linux下制作给ARM开发板使用的文件系统
- Android开发之ProgressBar字体随着进度条的加载而滚动
- Android 动态注册监听网络变化实例详解
- linux 服务器自动备份脚本的方法(mysql、附件备份)