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(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Android Studio使用Profiler来完成内存泄漏的定位
这篇文章主要介绍了Android Studio使用Profiler来完成内存泄漏的定位,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下2021-03-03Android中解决RecyclerView各种点击事件的方法
这篇文章主要介绍了Android中解决RecyclerView各种点击事件的方法,完美解决RecyclerView点击事件、长按事件、子项点击事件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2018-05-05Android TimePicker 直接输入的问题解决方案
这篇文章主要介绍了Android TimePicker 直接输入的问题解决方案的相关资料,需要的朋友可以参考下2017-04-04
最新评论