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