Android Socket连接(模拟心跳包,断线重连,发送数据等)

  • 首页
  • 博客
  • 学院
  • 下载
  • GitChat
  • TinyMind
  • 论坛
  • 问答
  • 商城
  • VIP
  • 活动
  • 招聘
  • ITeye
  • CSTO
喻志强的博客

耐心 细心 用心 传播正能量

RSS订阅
Android Socket连接(模拟心跳包,断线重连,发送数据等)

这两天做了一个项目是app通过socket连接自动炒菜机,给炒菜机发指令,炒菜机接收到指令会执行相应的操作。(程序虽然做的差不多了,然而我连炒菜机长什么样都没见过)

其实作为一个会做饭的程序猿,我坚信还是自己动手做的饭菜比较好吃,毕竟做饭还是很有趣的。

Android Socket连接(模拟心跳包,断线重连,发送数据等)_第1张图片

闲话不多说,因为是通过socket去连接炒菜机的,并且要求每两秒要给炒菜机发送一个指令,点击按钮的话也要发送相应的指令。 
所以要考虑一些问题,比如断线重连,数据发送失败了重连,要保持全局只有一个连接等等。


因为是要保证全局只能有一个连接,而且我们还需要在不同的Activity中发指令,因此肯定不能在需要发指令的界面中都去连接socket,这样一来不好管理,性能也不好,重复代码也会比较多,所以想了一下还是把socket放到service中比较好,发指令功能都放在service中即可。

记得要先给网络权限

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

下面我们来看看Service中的代码,其中有些细节是需要注意的 
1)我们要保证只有一个连接服务运行,所以在启动服务之前先判断一下连接服务是否正在运行,如果正在运行,就不再启动服务了。 
2)连接成功之后给出相应的通知,告诉连接者连接成功了,方便进行下一步操作,这里为了省事儿就直接用EventBus去通知了。也可以用广播的方式去通知。 
3)连接超时之后要注意先释放调之前的资源,然后重新初始化

package com.yzq.socketdemo.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.TabHost;
import android.widget.Toast;

import com.yzq.socketdemo.common.Constants;
import com.yzq.socketdemo.common.EventMsg;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.NoRouteToHostException;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Timer;
import java.util.TimerTask;


/**
 * Created by yzq on 2017/9/26.
 * 

* socket连接服务 */ public class SocketService extends Service { /*socket*/ private Socket socket; /*连接线程*/ private Thread connectThread; private Timer timer = new Timer(); private OutputStream outputStream; private SocketBinder sockerBinder = new SocketBinder(); private String ip; private String port; private TimerTask task; /*默认重连*/ private boolean isReConnect = true; private Handler handler = new Handler(Looper.getMainLooper()); @Override public IBinder onBind(Intent intent) { return sockerBinder; } public class SocketBinder extends Binder { /*返回SocketService 在需要的地方可以通过ServiceConnection获取到SocketService */ public SocketService getService() { return SocketService.this; } } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { /*拿到传递过来的ip和端口号*/ ip = intent.getStringExtra(Constants.INTENT_IP); port = intent.getStringExtra(Constants.INTENT_PORT); /*初始化socket*/ initSocket(); return super.onStartCommand(intent, flags, startId); } /*初始化socket*/ private void initSocket() { if (socket == null && connectThread == null) { connectThread = new Thread(new Runnable() { @Override public void run() { socket = new Socket(); try { /*超时时间为2秒*/ socket.connect(new InetSocketAddress(ip, Integer.valueOf(port)), 2000); /*连接成功的话 发送心跳包*/ if (socket.isConnected()) { /*因为Toast是要运行在主线程的 这里是子线程 所以需要到主线程哪里去显示toast*/ toastMsg("socket已连接"); /*发送连接成功的消息*/ EventMsg msg = new EventMsg(); msg.setTag(Constants.CONNET_SUCCESS); EventBus.getDefault().post(msg); /*发送心跳数据*/ sendBeatData(); } } catch (IOException e) { e.printStackTrace(); if (e instanceof SocketTimeoutException) { toastMsg("连接超时,正在重连"); releaseSocket(); } else if (e instanceof NoRouteToHostException) { toastMsg("该地址不存在,请检查"); stopSelf(); } else if (e instanceof ConnectException) { toastMsg("连接异常或被拒绝,请检查"); stopSelf(); } } } }); /*启动连接线程*/ connectThread.start(); } } /*因为Toast是要运行在主线程的 所以需要到主线程哪里去显示toast*/ private void toastMsg(final String msg) { handler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); } }); } /*发送数据*/ public void sendOrder(final String order) { if (socket != null && socket.isConnected()) { /*发送指令*/ new Thread(new Runnable() { @Override public void run() { try { outputStream = socket.getOutputStream(); if (outputStream != null) { outputStream.write((order).getBytes("gbk")); outputStream.flush(); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } else { toastMsg("socket连接错误,请重试"); } } /*定时发送数据*/ private void sendBeatData() { if (timer == null) { timer = new Timer(); } if (task == null) { task = new TimerTask() { @Override public void run() { try { outputStream = socket.getOutputStream(); /*这里的编码方式根据你的需求去改*/ outputStream.write(("test").getBytes("gbk")); outputStream.flush(); } catch (Exception e) { /*发送失败说明socket断开了或者出现了其他错误*/ toastMsg("连接断开,正在重连"); /*重连*/ releaseSocket(); e.printStackTrace(); } } }; } timer.schedule(task, 0, 2000); } /*释放资源*/ private void releaseSocket() { if (task != null) { task.cancel(); task = null; } if (timer != null) { timer.purge(); timer.cancel(); timer = null; } if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } outputStream = null; } if (socket != null) { try { socket.close(); } catch (IOException e) { } socket = null; } if (connectThread != null) { connectThread = null; } /*重新初始化socket*/ if (isReConnect) { initSocket(); } } @Override public void onDestroy() { super.onDestroy(); Log.i("SocketService", "onDestroy"); isReConnect = false; releaseSocket(); } }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272

好了,连接的service我们基本就做好了,先来看看效果,调试工具使用的是一个网络调试助手,免去我们写服务端的代码。 
来看看效果图:

Android Socket连接(模拟心跳包,断线重连,发送数据等)_第2张图片

可以看到,断线重连,连接成功自动发送数据,连接成功发消息这些都有了,实际上数据发送失败重连也是有的,不过模拟器上间隔时间很长,不知道怎么回事,真机没有问题。

解决了service下面就是Activity于service通信的问题了。这个就简单了,我们在service中提供了一个binder,我们可以通过binder来拿到service,然后调service的sendOrder()即可 
先来看看示例代码:

package com.yzq.socketdemo.activity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.EditText;

import com.yzq.socketdemo.R;
import com.yzq.socketdemo.service.SocketService;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;


/**
 * Created by yzq on 2017/9/26.
 * 

* mainActivity */ public class MainActivity extends AppCompatActivity { @BindView(R.id.contentEt) EditText contentEt; @BindView(R.id.sendBtn) Button sendBtn; private ServiceConnection sc; public SocketService socketService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindSocketService(); ButterKnife.bind(this); } private void bindSocketService() { /*通过binder拿到service*/ sc = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { SocketService.SocketBinder binder = (SocketService.SocketBinder) iBinder; socketService = binder.getService(); } @Override public void onServiceDisconnected(ComponentName componentName) { } }; Intent intent = new Intent(getApplicationContext(), SocketService.class); bindService(intent, sc, BIND_AUTO_CREATE); } @OnClick(R.id.sendBtn) public void onViewClicked() { String data = contentEt.getText().toString().trim(); socketService.sendOrder(data); } @Override protected void onDestroy() { super.onDestroy(); unbindService(sc); Intent intent = new Intent(getApplicationContext(), SocketService.class); stopService(intent); } }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

Android Socket连接(模拟心跳包,断线重连,发送数据等)_第3张图片

ok,大功告成 
下面是demo,我用的是android studio3.0预览版,可能gradle版本会高一些。 
socketDemo

文章标签:  android socket socket socket断线重连
个人分类:  Android
  • sinat_26710701
    暴躁的码字猴 2018-02-28 15:46:37 #3楼
    请问 你家炒菜机上市没,我去买一个
  • u011100532
    伤不起12 2017-12-07 10:39:57 #2楼
    能默默的问一个,怎么接收数据吗,我将inputstream用eventbus传到main界面,因为不停接收,会出现oom的
    查看回复(1)
  • wwwzwb
    wwwzwb 2017-10-15 22:45:13 #1楼
    不错,图文并茂还有源码,再看不明白就只能去工地搬砖了!
  • 上一页
  • 1
  • 下一页

android学习】断线重连机制

【解决问题】 android连接网络之后,当网络断开连接时,为了提高用户体验,android自动检测网络,当有网络时,用户无需进行多余操作,android端自动重新连接网络。 【解决方案】 1...

SunshineTan SunshineTan

2016-07-27 22:41:07

阅读数:7034

关于socket判断连接断开并重连

关于socket判断连接断开并重连 以下是个线程函数 UINT CMonitorDlg::ThreadFunction(LPVOID pParam) { WSADATA wsaData; SOCKET...

tengxiaoming tengxiaoming

2010-08-27 01:02:00

阅读数:8423

android-socket斷開之後重新連接 - CSDN博客

最后,将SocketClient.resetSocket();放入图片中的catch{}中,捕获异常的时候重新...Websocket SSL加密之android端(带重连) 最近在开发Android手机端的websocket通信...

2018-5-25

WebSocket安卓客户端实现详解(一)--连接建立与重连 - CSDN博客

WebSocket安卓客户端实现详解(一)–连接建立与重连 今年在公司第一个需求就是...android中使用webSocket通信 概述最近公司项目准备使用WebSocket实现消息推送功能,在...

2018-3-2

您有一张免费的北京车展门票等待领取美好购车节 · 顶新

WebSocket安卓客户端实现详解(一)--连接建立与重连

今年在公司第一个需求就是基于websocket写一个客户端消息中心,现在已经上线很久了在司机这种网络环境平均一天重连8次,自认为还是不错的.当时写的时候那个心酸啊,主要因为第一次写都不知道该从哪下手,...

zly921112 zly921112

2017-06-10 00:07:03

阅读数:19672

Android:这是一份很详细的Socket使用攻略 - CSDN博客

前言Socket的使用在Android的网络编程中非常重要今天我将带大家全面了解Socket及其使用方法 目录1.网络基础1.1 计算机网络分层计算机网络分为五层:物理层、数据链路层...

2018-5-2

android端 socket长连接 架构 - CSDN博客

看过包建强的《App研发录》之后对其中的基础Activity类封装感到惊讶,一直想找一种方式去解决关于app中使用socket长连接问题,如何实现简易的封装来达到主活动中涉及...

2018-5-28

Android Socket连接(心跳检测,断线重连,状态监测等)

2017年09月27日 13.06MB 下载

android-socket斷開之後重新連接

今天研究这个问题搞了整整一天啊!终于出来了,不过我没有多大的成就感,为什么呢?因为这是我学长的劳动成果。同样的问题,我却没想出来!心塞的很啊…… 不过还是要给大家分享一下,希望给大家带来帮助! ...

yqj234 yqj234

2016-04-27 10:24:49

阅读数:405

问题:解决Android中socket自动断开连接 - 酸豆角作坊 - CSDN博客

后来查找了资料,显示原来Android中蓝牙socket通信连接时长大概为120s,如果超过这个...• Android入门实战 • socket连接,判断连接中断,如果中断,并自动重连。 ...

2017-9-19

Android:这是一份很详细的Socket使用攻略 - CSDN博客

Socket的使用在 Android网络编程中非常重要 今天我将带大家全面了解 Socket及 其...Android:RxJava 结合 Retrofit 全面实现 网络请求出错重连 Android:RxJava 结合...

2017-12-27

Socket连接Android端心跳机制实现

前面用golang写的socket服务端请移步:http://blog.csdn.net/u010072711/article/details/760821761. 把socket链接和心跳功能都放在...

u010072711 u010072711

2017-07-25 22:36:27

阅读数:7978

打印机出租,新机销售,选弘顺瑞通,绿色节能办公的首选!弘顺瑞通 · 顶新

Android中Socket使用 - CSDN博客

Android Socket用法详解 2015-11-08 16:51 73人阅读 评论(0) 收藏 举报  分类: android基础(28)   在客户/服务器通信模式中, 客户端需要...

2018-4-19

Android:最全面的Socket使用解析 - CSDN博客

版权声明:本文为博主原创文章,未经博主允许不得转载,更多文章请继续关注Carson_Ho的博客! 目录(?)[+] 前...

2018-5-23

Android-----借助MINA框架实现长连接、短连接以及断线重连

前面我们分析了MINA框架的源码,大家可以从这里进行查看,这篇博客我们使用MINA来完成项目中经常会用到的长连接、短连接断线重连功能,直接开始了;         MINA本身...

hzw19920329 hzw19920329

2016-08-13 17:40:31

阅读数:6750

Android中判断socket通信断开

你好!这里是风筝的博客,欢迎和我一起交流。 如果本篇博客对您有帮助,或许可以在下方评论给我留个言呀。 可以引起网络连接关闭的情况有以下4种: 1.  直接调用Socket类的close方法...

Guet_Kite Guet_Kite

2017-04-21 19:20:25

阅读数:4411

Android:这是一份很详细的Socket使用攻略 - CSDN博客

最后。该关闭的流和 socket。是一定要关闭的。。。 Socket的使用在 Android网络编程中非常重要 今天我将带大家全面了解 Socket 及 其使用方法  目录 1...

2018-3-7

undefined

安卓 java有效判断Socket连接断开和安卓TCP测试APP(客户+服务端一体)

1. 利用socket提供的isConnected()与isClosed()方法来判断。但这种方式只是本地判断,只是本地操作connect()或close()方法后保存的一个状态,对于远程服务器主动断...

HelloMyPeople HelloMyPeople

2016-07-14 09:51:02

阅读数:5791

问题:解决Androidsocket自动断开连接

连接上蓝牙模块后,能够正常读数,蓝牙数据发送速率为0.03s每个。大概在发送了342个数据之后,突然接收不到数据了。...

pursue16 pursue16

2017-05-14 17:13:32

阅读数:2380

Android socket与服务器通信及心跳连接的实现

在项目中,有如下需求:Android客户端向服务器发送数据,收到服务器返回的数据发送成功标识后,客户端即与服务器建立数据一来一往的心跳连接,若服务器端断开时,客户端接收到通知,关闭Service停止发...

androidforwell androidforwell

2017-02-14 17:19:48

阅读数:6071

android socket 实现心跳包

//开一个新线程 new Thread(){ //用handle处理要发送的数据 Handler handler = new Handler(){ public voi...

mobei1983 mobei1983

2016-05-27 11:01:58

阅读数:594

Androidsocket连接(心跳检测)

2016年03月23日 2.78MB 下载

Android心跳包(一)——心跳实现

连接 测试服务器:  Socket基本上都这么一个流程。 public class Test { private static final int PORT = 1234; ...

github_27263697 github_27263697

2017-11-21 16:35:47

阅读数:441

Android上面如何使用带有心跳检测的Socket

由于移动设备的网络的复杂性,经常会出现网络断开,如果没有心跳包的检测,客户端只会在需要发送数据的时候才知道自己已经断线,会延误,甚至丢失服务器发送过来的数据。一下简单建立一个带有心跳检测的Socket...

cuishiying cuishiying

2015-08-12 00:45:53

阅读数:426

android连接心跳机制

在写之前,我们首先了解一下为什么android维护长连接需要心跳机制,首先我们知道,维护任何一个长连接都需要心跳机制,客户端发送一个心跳给 服务器,服务器给客户端一个心跳应答,这样就形成客户端服务器...

rabbit_in_android rabbit_in_android

2015-11-30 22:21:32

阅读数:19654

Android-socket的基本使用,发送文字和图片以及心跳

项目需求收集通过Socket向服务器发送图片,之前没搞过,网上搜搜写了下面的例子,勉强解决了需求。为了测试切换着方便,所以方法写的有点碎了。。。 原文地址 http://blog.csdn.net/...

qq_25806863 qq_25806863

2017-07-20 15:55:20

阅读数:1611

Android socket通信的长连接与心跳检测

Android开发中,我们可能需要和服务器保持连接不断开,这时需要用到socket通信的长连接,并且定时发送消息检测是否是连接状态——心跳检测。 我们需要一个客户端和一个服务器端的...

JJ583500596 JJ583500596

2017-08-02 17:13:15

阅读数:1234

AndroidAndroid心跳包详解

在做IM通信时,都会遇到这样一个概念:心跳包。又是一个比较抽象的概念,那么心跳包到底是什么呢? 之前做的机房预定系统里,使用的Socket和服务器通信。长连接测试服务器: Socket基本上都这么...

bless2015 bless2015

2016-09-27 14:04:08

阅读数:5026

Android socket通信长连接(心跳检测)

2016年06月17日 2.78MB 下载

个人资料

关注
原创
56
粉丝
147
喜欢
195
评论
244
等级:
访问:
19万+
积分:
2483
排名:
1万+
勋章:

我的个人网站

我的个人网站
我的Github

最新文章

  • Android获取SHA1值的详细步骤
  • 从天地初开到MVC再到MVP
  • rxjava2的相关封装
  • Kotlin Unresolved reference: 解决办法
  • Kotlin的变量和数据类型

博主专栏

  • Android Socket连接(模拟心跳包,断线重连,发送数据等)_第4张图片

    从零开始,学习web前端

    阅读量: 81096 21 篇
  • Android Socket连接(模拟心跳包,断线重连,发送数据等)_第5张图片

    Kotlin从入门到放弃java

    阅读量: 404 2 篇

归档

  • 2018年2月1篇
  • 2018年1月3篇
  • 2017年12月3篇
  • 2017年10月5篇
  • 2017年9月5篇
  • 2017年8月1篇
  • 2017年7月5篇
  • 2017年6月3篇
  • 2017年5月6篇
  • 2017年4月4篇
  • 2017年3月7篇
  • 2017年2月3篇
  • 2017年1月7篇
  • 2016年11月1篇
  • 2016年10月2篇
  • 2016年8月1篇

展开

热门文章

  • 超简单集成Android Zxing实现扫一扫二维码

    阅读量:24982

  • Android 底部导航栏 BottomNavigationBar的简单使用

    阅读量:15197

  • Android Studio3.x新的依赖方式(implementation、api、compileOnly)

    阅读量:12346

  • Angular项目目录结构详解

    阅读量:12136

  • Angular环境搭建

    阅读量:10864

  • 2


  • 收藏

  • 评论

  • 微信

  • 微博

  • QQ
关闭

你可能感兴趣的:(android,socket,socket,socket断线重连,Android)