Example of communication between Android and server via Socket

  • 2021-10-27 09:13:20
  • OfStack

1. First, write Server:


public class SocketServer {
 private static Socket mSocket;

 public static void main(String[] argc) {
  try {
   //1. Create 1 Server side Socket Namely ServerSocket Specifies the port to bind to and listens on this port 
   ServerSocket serverSocket = new ServerSocket(12345);
   InetAddress address = InetAddress.getLocalHost();
   String ip = address.getHostAddress();

   //2. Call accept() Waiting for client connection 
   System.out.println("~~~ The server is ready, waiting for the client to access ~ , server side ip Address : " + ip);
   mSocket = serverSocket.accept();

   //3. After connection, get the input stream and read the client information 
   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(" Message sent by the client " + info);
    if (info.equals(BackService.HEART_BEAT_STRING)) {
     sendmsg("ok");

    } else {
     sendmsg(" Information sent by the server " + info);

    }
   }

   mSocket.shutdownInput();
   mSocket.close();

  } catch (IOException e) {
   e.printStackTrace();
  }

}


 // Send information for each client that connects to the server 
 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();
  }
 }
}

2. AIDL is mainly used for Server and Client

AIDL is mainly written in the following three parts:

1. Create AIDL

1) Create the entity class to manipulate and implement the Parcelable interface for serialization/deserialization
2) Create a new aidl folder, in which the interface aidl file and the mapping aidl file of the entity class are created
3), Make project, generating Java file of Binder

2. Server side

1) Create an Service in which the Binder object instance generated above is created to implement the method defined by the interface
2), returned in onBind ()

3. Client

1) Realize the ServiceConnection interface and get the AIDL class in it
2), bindService ()
3) Call the operation request defined in the AIDL class

IBackService. aidl file


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);
}

The writing of Service is named BackService


public class BackService extends Service {
 private static final String TAG = "danxx";
 public static final String HEART_BEAT_STRING = "HeartBeat";// Heartbeat package content 
 /**
  *  Heart rate 
  */
 private static final long HEART_BEAT_RATE = 3 * 1000;
 /**
  *  Server ip Address 
  */
 public static final String HOST = "172.16.50.115";
 /**
  *  Server port number 
  */
 public static final int PORT = 12345;
 /**
  *  Server message reply broadcast 
  */
 public static final String MESSAGE_ACTION = "message_ACTION";
 /**
  *  Server heartbeat reply broadcast 
  */
 public static final String HEART_BEAT_ACTION = "heart_beat_ACTION";
 /**
  *  Read thread 
  */
 private ReadThread mReadThread;

 private LocalBroadcastManager mLocalBroadcastManager;
 /***/
 private WeakReference<Socket> mSocket;

 // For heart Beat
 private Handler mHandler = new Handler();
 /**
  *  Heartbeat task, calling yourself repeatedly 
  */
 private Runnable heartBeatRunnable = new Runnable() {

  @Override
  public void run() {
   if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
    boolean isSuccess = sendMsg(HEART_BEAT_STRING);// Send it 1 A \r\n Past   If the send fails, it is reinitialized 1 A socket
    if (!isSuccess) {
     mHandler.removeCallbacks(heartBeatRunnable);
     mReadThread.release();
     releaseLastSocket(mSocket);
     new InitSocketThread().start();
    }
   }
   mHandler.postDelayed(this, HEART_BEAT_RATE);
  }
 };

 private long sendTime = 0L;
 /**
  * aidl Communication callback 
  */
 private IBackService.Stub iBackService = new IBackService.Stub() {

  /**
   *  Receive content send message 
   * @param message  Messages to be sent to the server 
   * @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();// Every time it is sent as data, it is changed 1 Lower the last successful send time, saving heartbeat interval time 
  } else {
   return false;
  }
  return true;
 }

 private void initSocket() {// Initialization Socket
  try {
   //1. Create a client Socket Specify the server address and port 
   Socket so = new Socket(HOST, PORT);
   mSocket = new WeakReference<Socket>(so);
   mReadThread = new ReadThread(so);
   mReadThread.start();
   mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);// After successful initialization, you are ready to send heartbeat packets 
  } catch (UnknownHostException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 /**
  *  The heartbeat mechanism judges that socket After it has been disconnected, destroy the connection to facilitate re-creation of the connection 
  *
  * @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);
       // When you receive the message from the server, you will pass through Broadcast Send out 
       if (message.equals("ok")) {// Handle heartbeat recovery 
        Intent intent = new Intent(HEART_BEAT_ACTION);
        mLocalBroadcastManager.sendBroadcast(intent);

       } else {
        // Other message replies 
        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(" Server message :" + 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. Create a client Socket Specify the server address and port 
  Socket socket = new Socket("172.16.50.115", 12345);
  //2. Get the output stream and send information to the server 
  OutputStream os = socket.getOutputStream();
  PrintWriter printWriter = new PrintWriter(os); // Wrapping the output stream as a print stream 

  // Object of the client IP Address 
  InetAddress address = InetAddress.getLocalHost();
  String ip = address.getHostAddress();
  printWriter.write(" Client: ~" + ip + "~  Access the server! ! ");
  printWriter.flush();
  socket.shutdownInput();
  socket.close();
 }
}

Source address


Related articles: