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);//就发送一个\r\n过去 如果发送失败,就重新初始化一个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 + "\r\n";
      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();
 }
}

源码地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • android基于socket的局域网内服务器与客户端加密通信

    实现了基本的socket通信(即两台设备,一台用作服务器,一台用作客户端),服务器进行监听,客户端发送加密数据到服务器,服务器进行解密得到明文. 注意:本项目中使用了ButterKnife及EventBus作为辅助工具,通信建立时默认网络正常(未做局域网网络环境检测),加密方式为AES加密 1.效果图: (1)客户端 (2)服务器端 2.界面布局部分 (1)服务器端布局 function_socket_server.xml <?xml version="1.0" encoding

  • android利用websocket协议与服务器通信

    最近做一个项目,需求中需要服务器主动推送消息到客户端.这样的话一般的http连接就不能使用了.博主问了个朋友,向我推荐websocket协议,特此测试了一下,发现效果很好. android本身没有websocket的库,需要自己下载 ,下载地址. 客户端代码: 界面布局自己写,很简单的两个button package com.example.test; import com.example.test.R; import android.app.Activity; import android.o

  • Android编程之客户端通过socket与服务器通信的方法

    本文实例讲述了Android编程之客户端通过socket与服务器通信的方法.分享给大家供大家参考,具体如下: 下面是一个demo,Android客户端通过socket与服务器通信. 由于Android里面可以完全使用java.io.*包和java.net.*包,那么,实际上,逻辑部分与J2SE没有区别.只是UI代码不一样. Android客户端通过socket与服务器通信分为下面5步: (1)通过IP地址和端口实例化Socket,请求连接服务器: 复制代码 代码如下: socket = new

  • python服务器与android客户端socket通信实例

    本文实例讲述了python服务器与android客户端socket通信的方法.分享给大家供大家参考.具体实现方法如下: 首先,服务器端使用python完成,下面为python代码: 复制代码 代码如下: #server.py  import socket  def getipaddrs(hostname):#只是为了显示IP,仅仅测试一下      result = socket.getaddrinfo(hostname, None, 0, socket.SOCK_STREAM)      re

  • 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 = Inet

  • 详解Android 通过Socket 和服务器通讯(附demo)

    Android 通过Socket 和服务器通讯,是一种比较常用的通讯方式,时间比较紧,说下大致的思路,希望能帮到使用socket 进行通信的人 (1)开启一个线程发送消息    SocketOutputThread 消息是放在队列里的,当有消息后,进入队列,线程唤醒,发送消息,并反馈发送是否成功的回调 (2)开启一个线程接受服务器消息 SocketInputThread 为了防止一直收数据,浪费电池的电,采用NIO的方式读socket的数据,这个是本文的关键 (3)开启一个线程,做心跳,防止so

  • Android编程实现TCP、UDP客户端通信功能示例

    本文实例讲述了Android编程实现TCP.UDP客户端通信功能.分享给大家供大家参考,具体如下: 在进行Android开发的过程中,免不了,要开发TCP/UDP通讯的程序,下面这两段代码,分别介绍了TCP/UCP通过的一个实例: 代码一 TCP通讯: private void tcpdata() { try { Socket s = new Socket("192.168.0.25", 65500); // outgoing stream redirect to socket Out

  • Android中Uri和Path之间的转换的示例代码

    Android中Uri和Path之间的转换 原因 调用系统拍照应用,拍照后要保存图片,那么我们需要指定一个存储图片路径的Uri.这就涉及到如何将file path转换为Uri.有时候我们还需要根据照片的路径得到照片的media Uri,那么又该如何转换呢? Android Uri to Path 现在遇到的常规Uri有两种: 媒体文件的Uri是content://, 表示这是一个数据库数据.去数据库查询正常返回. 其他的文件Uri是file://, 表示这个是一个文件.这个uri是通过Uri.f

  • Python socket模块实现的udp通信功能示例

    本文实例讲述了Python socket模块实现的udp通信功能.分享给大家供大家参考,具体如下: socket介绍 socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是: 它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ 聊天.收发 email 等等. 模拟udp_socket客户端(发送端):udp_client.py #coding=utf-8 import socket # 获

  • java实现socket从服务器连续获取消息的示例

    服务器端我们用软件模拟,是一个很小巧的软件,下载软件NetAssist:http://xiazai.jb51.net/201403/tools/NetAssist(jb51.net).rar 第二步贴上我们客户端的代码: 复制代码 代码如下: import java.io.DataInputStream; import java.io.IOException;import java.net.Socket; public class Client {      public static fina

  • android使用Socket通信实现多人聊天应用

    使用Socket实现多人聊天应用,供大家参考,具体内容如下 在讲scoket通信器先可以先了解一下网络协议 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在"无差别"的网络之上.可以将网络协议分为四层,从高到低依次为:应用层.传输层.网络层.链路层. 两种Socket类型的基本通信 TCP是一个可靠的.面向连接的协议.它可以保证数据从连接的一方传递到另一方,并且发送数据的顺序

  • Android完整Socket解决方案

    整体步骤流程 先来说一下整体的步骤思路吧: 发送 UDP 广播,大家都知道 UDP 广播的特性是整个网段的设备都可以收到这个消息. 接收方收到了 UDP 的广播,将自己的 ip 地址,和双方约定的端口号,回复给 UDP 的发送方. 发送方拿到了对方的 ip 地址以及端口号,就可以发起 TCP 请求了,建立 TCP 连接. 保持一个 TCP 心跳,如果发现对方不在了,超时重复 1 步骤,重新建立联系. 整体的步骤就和上述的一样,下面用代码展开: 搭建 UDP 模块 public UDPSocket

随机推荐