当前位置:   article > 正文

Android基于WebSocket实现局域网互联_android websocket server

android websocket server

记录一下Android 基于WebSoket局域网互联技术,大家互相交流

准备工作

1、导入依赖

implementation "org.java-websocket:Java-WebSocket:1.5.1"

2,配置权限

申请网络权限(必须)

  1. <uses-permission android:name="android.permission.INTERNET" />
  2. 申请wifi相关权限(必须)
  3. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

工具类:IPToolsUtils 用于查询IP

  1. import com.tencent.mmkv.MMKV;
  2. import java.net.InetAddress;
  3. import java.net.InetSocketAddress;
  4. import java.net.NetworkInterface;
  5. import java.net.Socket;
  6. import java.net.SocketException;
  7. import java.util.Enumeration;
  8. import java.util.Random;
  9. import java.util.regex.Matcher;
  10. import java.util.regex.Pattern;
  11. public class IPToolsUtils {
  12. //匹配C类地址的IP
  13. public static final String regexCIp = "^192\\.168\\.(\\d{1}|[1-9]\\d|1\\d{2}|2[0-4]\\d|25\\d)\\.(\\d{1}|[1-9]\\d|1\\d{2}|2[0-4]\\d|25\\d)$";
  14. //匹配A类地址
  15. public static final String regexAIp = "^10\\.(\\d{1}|[1-9]\\d|1\\d{2}|2[0-4]\\d|25\\d)\\.(\\d{1}|[1-9]\\d|1\\d{2}|2[0-4]\\d|25\\d)\\.(\\d{1}|[1-9]\\d|1\\d{2}|2[0-4]\\d|25\\d)$";
  16. //匹配B类地址
  17. public static final String regexBIp = "^172\\.(1[6-9]|2\\d|3[0-1])\\.(\\d{1}|[1-9]\\d|1\\d{2}|2[0-4]\\d|25\\d)\\.(\\d{1}|[1-9]\\d|1\\d{2}|2[0-4]\\d|25\\d)$";
  18. public static String getHostIp() {
  19. String hostIp;
  20. Pattern ip = Pattern.compile("(" + regexAIp + ")|" + "(" + regexBIp + ")|" + "(" + regexCIp + ")");
  21. Enumeration<NetworkInterface> networkInterfaces = null;
  22. try {
  23. networkInterfaces = NetworkInterface.getNetworkInterfaces();
  24. } catch (SocketException e) {
  25. e.printStackTrace();
  26. }
  27. InetAddress address;
  28. while (networkInterfaces.hasMoreElements()) {
  29. NetworkInterface networkInterface = networkInterfaces.nextElement();
  30. Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
  31. while (inetAddresses.hasMoreElements()) {
  32. address = inetAddresses.nextElement();
  33. String hostAddress = address.getHostAddress();
  34. Matcher matcher = ip.matcher(hostAddress);
  35. if (matcher.matches()) {
  36. hostIp = hostAddress;
  37. return hostIp;
  38. }
  39. }
  40. }
  41. return null;
  42. }
  43. private static void bindPort(String host, int port) throws Exception{
  44. Socket s = new Socket();
  45. s.bind(new InetSocketAddress(host, port));
  46. s.close();
  47. }
  48. public static int getFreePort(){//判断端口是否可用
  49. int port=MMKV.defaultMMKV().decodeInt("port",8888);
  50. try{
  51. bindPort("0.0.0.0", port);
  52. bindPort(InetAddress.getLocalHost().getHostAddress(),port);
  53. }
  54. catch (Exception e)
  55. {
  56. port=new Random().nextInt(65535);
  57. MMKV.defaultMMKV().encode("port",port);
  58. getFreePort();
  59. }
  60. return port;
  61. }
  62. public static boolean isIssued(int port){//判断端口是否可用
  63. try{
  64. bindPort("0.0.0.0", port);
  65. bindPort(InetAddress.getLocalHost().getHostAddress(),port);
  66. return true;
  67. }
  68. catch (Exception e)
  69. {
  70. return false;
  71. }
  72. }
  73. }

服务端WEbSoketClient代码实现

  1. import android.util.Log;
  2. import org.greenrobot.eventbus.EventBus;
  3. import org.java_websocket.WebSocket;
  4. import org.java_websocket.handshake.ClientHandshake;
  5. import java.net.InetSocketAddress;
  6. import static com.tuosi.websocketchartdemo.MainActivity.isServer;
  7. /**
  8. * guguangxian
  9. */
  10. public class WebSocketServer extends org.java_websocket.server.WebSocketServer{
  11. private static WebSocketServer websocketServer;
  12. WebSocketServer(InetSocketAddress host){
  13. super(host);
  14. }
  15. @Override
  16. public void onOpen(WebSocket conn, ClientHandshake handshake) {
  17. Log.d("WebSocketServer","onOpen():连接到: "+getRemoteSocketAddress(conn));
  18. EventBus.getDefault().post(new MessageEvent(1,"onOpen:"+getRemoteSocketAddress(conn)));
  19. isServer=true;
  20. }
  21. @Override
  22. public void onClose(WebSocket conn, int code, String reason, boolean remote) {
  23. Log.d("WebSocketServer","onClose");
  24. EventBus.getDefault().post(new MessageEvent(1,"onClose:"+reason));
  25. }
  26. @Override
  27. public void onMessage(WebSocket conn, String message) {
  28. Log.d("WebSocketServer","onMessage"+message);
  29. EventBus.getDefault().post(new MessageEvent(2,getRemoteSocketAddress(conn)+message));
  30. }
  31. @Override
  32. public void onError(WebSocket conn, Exception ex) {
  33. Log.d("WebSocketServer","onError"+ex.toString());
  34. EventBus.getDefault().post(new MessageEvent(1,"onError:"+ex.toString()));
  35. }
  36. @Override
  37. public void onStart() {
  38. Log.d("WebSocketServer","onStart:"+websocketServer.getAddress());
  39. EventBus.getDefault().post(new MessageEvent(1,"onStart:服务器已就绪"+websocketServer.getAddress()));
  40. }
  41. public static void ready(){
  42. String ip = IPToolsUtils.getHostIp();
  43. InetSocketAddress myHost = new InetSocketAddress(ip, 8080);
  44. WebSocketServer websocketServer = new WebSocketServer(myHost);
  45. try {
  46. websocketServer.start();
  47. } catch (Exception e) {
  48. e.printStackTrace();
  49. }
  50. WebSocketServer.websocketServer = websocketServer;
  51. }
  52. public static void Stop() {
  53. try {
  54. websocketServer.stop();
  55. } catch (Exception e) {
  56. e.printStackTrace();
  57. }
  58. }
  59. public static void Send(String string) {
  60. try {
  61. websocketServer.broadcast(string);
  62. //websocketServer.broadcast(string,clients);//Collection<WebSocket> clients,指定发送到哪个客户端
  63. } catch (Exception e) {
  64. e.printStackTrace();
  65. }
  66. }
  67. }

客户端代码实现

  1. import android.os.Looper;
  2. import android.util.Log;
  3. import org.greenrobot.eventbus.EventBus;
  4. import org.java_websocket.exceptions.WebsocketNotConnectedException;
  5. import org.java_websocket.handshake.ServerHandshake;
  6. import java.net.URI;
  7. import static com.tuosi.websocketchartdemo.MainActivity.isClient;
  8. /**
  9. * guguangxian
  10. */
  11. public class WebSocketClient extends org.java_websocket.client.WebSocketClient {
  12. public WebSocketClient(URI serverUri) {
  13. super(serverUri);
  14. }
  15. @Override
  16. public void onOpen(ServerHandshake handshakedata) {
  17. Log.d("WebSocketClient","onOpen"+"成功连接到:"+getRemoteSocketAddress());
  18. EventBus.getDefault().post(new MessageEvent(1,"onOpen:"+getRemoteSocketAddress()));
  19. isClient=true;
  20. }
  21. @Override
  22. public void onMessage(String message) {
  23. Log.d("WebSocketClient","onMessage"+message);
  24. EventBus.getDefault().post(new MessageEvent(2,getRemoteSocketAddress()+":"+message));
  25. }
  26. @Override
  27. public void onClose(int code, String reason, boolean remote) {
  28. Log.d("WebSocketClient","onClose");
  29. EventBus.getDefault().post(new MessageEvent(1,"onClose:"+reason));
  30. }
  31. @Override
  32. public void onError(Exception ex) {
  33. Log.d("WebSocketClient","onError");
  34. EventBus.getDefault().post(new MessageEvent(505,"onError:"+ex.toString()));
  35. }
  36. private static WebSocketClient webSocketClient;
  37. public static boolean connect(String ip) {
  38. if (webSocketClient != null) {
  39. Release();
  40. }
  41. if (webSocketClient == null ) {
  42. URI uri = URI.create("ws://"+ip+":8080/");
  43. webSocketClient = new WebSocketClient(uri);
  44. }
  45. try {
  46. webSocketClient.connect();
  47. return true;
  48. } catch (Exception e) {
  49. e.printStackTrace();
  50. return false;
  51. }
  52. }
  53. public static void Release() {
  54. Close();
  55. webSocketClient = null;
  56. }
  57. public static void Close() {
  58. if (webSocketClient == null) return;
  59. if (!webSocketClient.isOpen()) return;
  60. try {
  61. webSocketClient.connect();
  62. } catch (Exception e) {
  63. e.printStackTrace();
  64. }
  65. }
  66. public static void Send(String string) {
  67. if (webSocketClient == null) return;
  68. if (!webSocketClient.isOpen())
  69. Reconnect();
  70. try {
  71. webSocketClient.send(string);
  72. } catch (WebsocketNotConnectedException e) {
  73. e.printStackTrace();
  74. }
  75. }
  76. public static boolean Reconnect() {
  77. if (webSocketClient == null) return false;
  78. if (webSocketClient.isOpen()) return true;
  79. try {
  80. webSocketClient.connect();
  81. return true;
  82. } catch (Exception e) {
  83. e.printStackTrace();
  84. return false;
  85. }
  86. }
  87. }

使用案例

  1. import androidx.appcompat.app.AppCompatActivity;
  2. import androidx.core.app.ActivityCompat;
  3. import android.Manifest;
  4. import android.content.Context;
  5. import android.content.pm.PackageManager;
  6. import android.net.wifi.WifiInfo;
  7. import android.net.wifi.WifiManager;
  8. import android.os.Build;
  9. import android.os.Bundle;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.view.ViewGroup;
  13. import android.widget.Button;
  14. import android.widget.EditText;
  15. import android.widget.LinearLayout;
  16. import android.widget.TextView;
  17. import android.widget.Toast;
  18. import com.tencent.mmkv.MMKV;
  19. import org.greenrobot.eventbus.EventBus;
  20. import org.greenrobot.eventbus.Subscribe;
  21. import org.greenrobot.eventbus.ThreadMode;
  22. import java.net.URI;
  23. import java.util.concurrent.ExecutorService;
  24. import java.util.concurrent.Executors;
  25. public class MainActivity extends AppCompatActivity {
  26. Button ready;
  27. Button connect;
  28. Button send;
  29. LinearLayout linearLayout;
  30. TextView textView;
  31. EditText editText;
  32. public static boolean isServer = false;
  33. public static boolean isClient = false;
  34. public static int index = 191;
  35. @Override
  36. protected void onCreate(Bundle savedInstanceState) {
  37. super.onCreate(savedInstanceState);
  38. setContentView(R.layout.activity_main);
  39. linearLayout = findViewById(R.id.linearLayout);
  40. textView = findViewById(R.id.TextView2);
  41. ready = findViewById(R.id.ready);
  42. connect = findViewById(R.id.connect);
  43. editText = findViewById(R.id.editText);
  44. ready.setOnClickListener(v -> WebSocketServer.ready());
  45. connect.setOnClickListener(v -> {
  46. // String ip = NetWorkUtil.getHostIp();
  47. // WebSocketClient.connect("192.168.1.193");
  48. // executorService.execute(thread);
  49. thread=new SessionThread();
  50. thread.start();
  51. });
  52. send = findViewById(R.id.send);
  53. send.setOnClickListener(v -> {
  54. String message = editText.getText().toString();
  55. if (message.equals("")) {
  56. Toast.makeText(MainActivity.this, "禁止发送空消息", Toast.LENGTH_SHORT).show();
  57. return;
  58. }
  59. if (isServer) {
  60. WebSocketServer.Send(message);
  61. addText("我:" + message);
  62. } else if (isClient) {
  63. WebSocketClient.Send(message);
  64. addText("我:" + message);
  65. } else {
  66. Toast.makeText(MainActivity.this, "未连接", Toast.LENGTH_SHORT).show();
  67. }
  68. });
  69. MMKV.initialize(this);
  70. EventBus.getDefault().register(this);
  71. }
  72. SessionThread thread;
  73. @Subscribe(threadMode = ThreadMode.MAIN)
  74. public synchronized void MessageEventBusa(MessageEvent messageEvent) {
  75. String string = messageEvent.getString();
  76. switch (messageEvent.getCode()) {
  77. case 1://
  78. textView.setText(string);
  79. break;
  80. case 2:
  81. addText(string);
  82. case 505:
  83. if (isClient) {
  84. return;
  85. }
  86. textView.setText(string);
  87. ++index;
  88. thread=null;
  89. thread = new SessionThread();
  90. thread.start();
  91. // executorService.execute(thread);
  92. break;
  93. }
  94. }
  95. private void addText(String string) {
  96. TextView textView = new TextView(this);
  97. LinearLayout.LayoutParams lllp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  98. textView.setText(string);
  99. linearLayout.addView(textView, lllp);
  100. }
  101. @Override
  102. protected void onDestroy() {
  103. super.onDestroy();
  104. EventBus.getDefault().unregister(this);
  105. }
  106. /* 发送进程 */
  107. private class SessionThread extends Thread {
  108. @Override
  109. public void run() {
  110. synchronized (this) {
  111. Log.e("wifiInfo", "index="+index);
  112. if (index > 255) {
  113. return;
  114. }
  115. try {
  116. String ipStart = "", ipEnd = "";
  117. //获取wifi服务
  118. WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
  119. if (wifiManager != null) {
  120. if (!wifiManager.isWifiEnabled())
  121. wifiManager.setWifiEnabled(true);
  122. WifiInfo wifiInfo = wifiManager.getConnectionInfo();
  123. int ipAddress = wifiInfo.getIpAddress();
  124. String str = intToIp(ipAddress);
  125. String[] ip = str.split("\\.");
  126. if (ip.length == 4) {
  127. ipStart = (ip[0] + "." + ip[1] + "." + ip[2] + ".2");
  128. ipEnd = (ip[0] + "." + ip[1] + "." + ip[2] + ".255");
  129. }
  130. }
  131. Log.e("wifiInfo", "startIP=" + ipStart);
  132. String[] startStr = ipStart.split("\\.");
  133. String[] endStr = ipEnd.split("\\.");
  134. // 扫描设备
  135. int startInt = Integer.parseInt(startStr[3]);
  136. int endInt = Integer.parseInt(endStr[3]);
  137. if (startStr.length == endStr.length && startStr[0].equals(endStr[0]) && startStr[1].equals(endStr[1]) && startStr[2].equals(endStr[2])) {
  138. int num = endInt - startInt;
  139. if (num > -1) {
  140. WebSocketClient[] websocket = new WebSocketClient[endInt - startInt + 1];
  141. String ipAddress = startStr[0] + "." + startStr[1] + "." + startStr[2] + ".";
  142. Log.e("wifiInfo", "ipAddress=" + ipAddress);
  143. String ipServer = ipAddress + index;
  144. WebSocketClient.connect(ipServer);
  145. Log.e("wifiInfo", "ipServer=" + ipServer);
  146. }
  147. }
  148. } catch (Exception e) {
  149. e.printStackTrace();
  150. }
  151. }
  152. }
  153. }
  154. private String intToIp(int i) {
  155. return (i & 0xFF) + "." +
  156. ((i >> 8) & 0xFF) + "." +
  157. ((i >> 16) & 0xFF) + "." +
  158. (i >> 24 & 0xFF);
  159. }
  160. }

xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <Button
  9. android:id="@+id/ready"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:layout_marginTop="8dp"
  13. android:text="等待连接"
  14. app:layout_constraintBottom_toBottomOf="parent"
  15. app:layout_constraintHorizontal_bias="0.359"
  16. app:layout_constraintLeft_toLeftOf="parent"
  17. app:layout_constraintRight_toRightOf="parent"
  18. app:layout_constraintTop_toTopOf="parent"
  19. app:layout_constraintVertical_bias="0.011" />
  20. <Button
  21. android:id="@+id/connect"
  22. android:layout_width="wrap_content"
  23. android:layout_height="wrap_content"
  24. android:text="发起连接"
  25. app:layout_constraintBottom_toBottomOf="parent"
  26. app:layout_constraintHorizontal_bias="0.049"
  27. app:layout_constraintLeft_toLeftOf="parent"
  28. app:layout_constraintRight_toRightOf="parent"
  29. app:layout_constraintTop_toTopOf="parent"
  30. app:layout_constraintVertical_bias="0.023" />
  31. <TextView
  32. android:id="@+id/TextView2"
  33. android:layout_width="match_parent"
  34. android:layout_height="50dp"
  35. android:layout_marginTop="8dp"
  36. android:text="连接到xxx"
  37. app:layout_constraintTop_toBottomOf="@+id/ready">
  38. </TextView>
  39. <LinearLayout
  40. android:id="@+id/linearLayout"
  41. android:layout_width="match_parent"
  42. android:layout_height="300dp"
  43. android:layout_marginTop="8dp"
  44. android:layout_marginBottom="8dp"
  45. android:orientation="vertical"
  46. app:layout_constraintBottom_toBottomOf="parent"
  47. app:layout_constraintTop_toBottomOf="@+id/TextView2"
  48. app:layout_constraintVertical_bias="0.0"
  49. tools:layout_editor_absoluteX="0dp">
  50. </LinearLayout>
  51. <EditText
  52. android:singleLine="true"
  53. android:id="@+id/editText"
  54. android:layout_width="match_parent"
  55. android:layout_height="100dp"
  56. android:layout_marginTop="8dp"
  57. app:layout_constraintTop_toBottomOf="@+id/linearLayout"
  58. tools:layout_editor_absoluteX="16dp" />
  59. <Button
  60. android:id="@+id/send"
  61. android:layout_width="match_parent"
  62. android:layout_height="50dp"
  63. android:layout_marginTop="8dp"
  64. app:layout_constraintTop_toBottomOf="@+id/editText"
  65. android:text="发送"
  66. tools:layout_editor_absoluteX="0dp" />
  67. </androidx.constraintlayout.widget.ConstraintLayout>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/758367
推荐阅读
相关标签
  

闽ICP备14008679号