赞
踩
记录一下Android 基于WebSoket局域网互联技术,大家互相交流
准备工作
1、导入依赖
implementation "org.java-websocket:Java-WebSocket:1.5.1"
2,配置权限
申请网络权限(必须)
- <uses-permission android:name="android.permission.INTERNET" />
- 申请wifi相关权限(必须)
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
工具类:IPToolsUtils 用于查询IP
- import com.tencent.mmkv.MMKV;
-
- import java.net.InetAddress;
- import java.net.InetSocketAddress;
- import java.net.NetworkInterface;
- import java.net.Socket;
- import java.net.SocketException;
- import java.util.Enumeration;
- import java.util.Random;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
-
- public class IPToolsUtils {
-
- //匹配C类地址的IP
- 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)$";
- //匹配A类地址
- 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)$";
- //匹配B类地址
- 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)$";
-
-
- public static String getHostIp() {
- String hostIp;
- Pattern ip = Pattern.compile("(" + regexAIp + ")|" + "(" + regexBIp + ")|" + "(" + regexCIp + ")");
- Enumeration<NetworkInterface> networkInterfaces = null;
- try {
- networkInterfaces = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e) {
- e.printStackTrace();
- }
- InetAddress address;
- while (networkInterfaces.hasMoreElements()) {
- NetworkInterface networkInterface = networkInterfaces.nextElement();
- Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
- while (inetAddresses.hasMoreElements()) {
- address = inetAddresses.nextElement();
- String hostAddress = address.getHostAddress();
- Matcher matcher = ip.matcher(hostAddress);
- if (matcher.matches()) {
- hostIp = hostAddress;
- return hostIp;
- }
-
- }
- }
- return null;
- }
- private static void bindPort(String host, int port) throws Exception{
- Socket s = new Socket();
- s.bind(new InetSocketAddress(host, port));
- s.close();
- }
- public static int getFreePort(){//判断端口是否可用
- int port=MMKV.defaultMMKV().decodeInt("port",8888);
- try{
- bindPort("0.0.0.0", port);
- bindPort(InetAddress.getLocalHost().getHostAddress(),port);
- }
- catch (Exception e)
- {
- port=new Random().nextInt(65535);
- MMKV.defaultMMKV().encode("port",port);
- getFreePort();
- }
- return port;
- }
- public static boolean isIssued(int port){//判断端口是否可用
- try{
- bindPort("0.0.0.0", port);
- bindPort(InetAddress.getLocalHost().getHostAddress(),port);
- return true;
- }
- catch (Exception e)
- {
- return false;
- }
- }
-
- }

服务端WEbSoketClient代码实现
- import android.util.Log;
-
- import org.greenrobot.eventbus.EventBus;
- import org.java_websocket.WebSocket;
- import org.java_websocket.handshake.ClientHandshake;
- import java.net.InetSocketAddress;
-
- import static com.tuosi.websocketchartdemo.MainActivity.isServer;
-
- /**
- * guguangxian
- */
- public class WebSocketServer extends org.java_websocket.server.WebSocketServer{
-
- private static WebSocketServer websocketServer;
- WebSocketServer(InetSocketAddress host){
- super(host);
- }
- @Override
- public void onOpen(WebSocket conn, ClientHandshake handshake) {
- Log.d("WebSocketServer","onOpen():连接到: "+getRemoteSocketAddress(conn));
- EventBus.getDefault().post(new MessageEvent(1,"onOpen:"+getRemoteSocketAddress(conn)));
- isServer=true;
- }
- @Override
- public void onClose(WebSocket conn, int code, String reason, boolean remote) {
- Log.d("WebSocketServer","onClose");
- EventBus.getDefault().post(new MessageEvent(1,"onClose:"+reason));
- }
- @Override
- public void onMessage(WebSocket conn, String message) {
- Log.d("WebSocketServer","onMessage"+message);
- EventBus.getDefault().post(new MessageEvent(2,getRemoteSocketAddress(conn)+message));
- }
- @Override
- public void onError(WebSocket conn, Exception ex) {
- Log.d("WebSocketServer","onError"+ex.toString());
- EventBus.getDefault().post(new MessageEvent(1,"onError:"+ex.toString()));
- }
- @Override
- public void onStart() {
- Log.d("WebSocketServer","onStart:"+websocketServer.getAddress());
- EventBus.getDefault().post(new MessageEvent(1,"onStart:服务器已就绪"+websocketServer.getAddress()));
-
- }
- public static void ready(){
- String ip = IPToolsUtils.getHostIp();
- InetSocketAddress myHost = new InetSocketAddress(ip, 8080);
- WebSocketServer websocketServer = new WebSocketServer(myHost);
- try {
- websocketServer.start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- WebSocketServer.websocketServer = websocketServer;
- }
-
- public static void Stop() {
- try {
- websocketServer.stop();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public static void Send(String string) {
- try {
- websocketServer.broadcast(string);
- //websocketServer.broadcast(string,clients);//Collection<WebSocket> clients,指定发送到哪个客户端
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
-
- }

客户端代码实现
- import android.os.Looper;
- import android.util.Log;
-
- import org.greenrobot.eventbus.EventBus;
- import org.java_websocket.exceptions.WebsocketNotConnectedException;
- import org.java_websocket.handshake.ServerHandshake;
- import java.net.URI;
-
- import static com.tuosi.websocketchartdemo.MainActivity.isClient;
-
- /**
- * guguangxian
- */
- public class WebSocketClient extends org.java_websocket.client.WebSocketClient {
- public WebSocketClient(URI serverUri) {
- super(serverUri);
- }
- @Override
- public void onOpen(ServerHandshake handshakedata) {
- Log.d("WebSocketClient","onOpen"+"成功连接到:"+getRemoteSocketAddress());
- EventBus.getDefault().post(new MessageEvent(1,"onOpen:"+getRemoteSocketAddress()));
- isClient=true;
-
- }
- @Override
- public void onMessage(String message) {
- Log.d("WebSocketClient","onMessage"+message);
- EventBus.getDefault().post(new MessageEvent(2,getRemoteSocketAddress()+":"+message));
-
- }
- @Override
- public void onClose(int code, String reason, boolean remote) {
- Log.d("WebSocketClient","onClose");
- EventBus.getDefault().post(new MessageEvent(1,"onClose:"+reason));
-
- }
- @Override
- public void onError(Exception ex) {
- Log.d("WebSocketClient","onError");
- EventBus.getDefault().post(new MessageEvent(505,"onError:"+ex.toString()));
-
- }
- private static WebSocketClient webSocketClient;
-
- public static boolean connect(String ip) {
- if (webSocketClient != null) {
- Release();
- }
- if (webSocketClient == null ) {
- URI uri = URI.create("ws://"+ip+":8080/");
- webSocketClient = new WebSocketClient(uri);
- }
- try {
- webSocketClient.connect();
- return true;
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
- public static void Release() {
- Close();
- webSocketClient = null;
- }
- public static void Close() {
- if (webSocketClient == null) return;
- if (!webSocketClient.isOpen()) return;
- try {
- webSocketClient.connect();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public static void Send(String string) {
- if (webSocketClient == null) return;
- if (!webSocketClient.isOpen())
- Reconnect();
- try {
- webSocketClient.send(string);
- } catch (WebsocketNotConnectedException e) {
- e.printStackTrace();
- }
- }
- public static boolean Reconnect() {
- if (webSocketClient == null) return false;
- if (webSocketClient.isOpen()) return true;
- try {
- webSocketClient.connect();
- return true;
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
- }

使用案例
- import androidx.appcompat.app.AppCompatActivity;
- import androidx.core.app.ActivityCompat;
-
- import android.Manifest;
- import android.content.Context;
- import android.content.pm.PackageManager;
- import android.net.wifi.WifiInfo;
- import android.net.wifi.WifiManager;
- import android.os.Build;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- import android.widget.Toast;
-
- import com.tencent.mmkv.MMKV;
-
- import org.greenrobot.eventbus.EventBus;
- import org.greenrobot.eventbus.Subscribe;
- import org.greenrobot.eventbus.ThreadMode;
-
- import java.net.URI;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
-
- public class MainActivity extends AppCompatActivity {
- Button ready;
- Button connect;
- Button send;
- LinearLayout linearLayout;
- TextView textView;
- EditText editText;
- public static boolean isServer = false;
- public static boolean isClient = false;
- public static int index = 191;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- linearLayout = findViewById(R.id.linearLayout);
- textView = findViewById(R.id.TextView2);
- ready = findViewById(R.id.ready);
- connect = findViewById(R.id.connect);
- editText = findViewById(R.id.editText);
- ready.setOnClickListener(v -> WebSocketServer.ready());
- connect.setOnClickListener(v -> {
- // String ip = NetWorkUtil.getHostIp();
- // WebSocketClient.connect("192.168.1.193");
- // executorService.execute(thread);
- thread=new SessionThread();
- thread.start();
- });
- send = findViewById(R.id.send);
- send.setOnClickListener(v -> {
- String message = editText.getText().toString();
- if (message.equals("")) {
- Toast.makeText(MainActivity.this, "禁止发送空消息", Toast.LENGTH_SHORT).show();
- return;
- }
- if (isServer) {
- WebSocketServer.Send(message);
- addText("我:" + message);
-
- } else if (isClient) {
- WebSocketClient.Send(message);
- addText("我:" + message);
- } else {
- Toast.makeText(MainActivity.this, "未连接", Toast.LENGTH_SHORT).show();
- }
- });
- MMKV.initialize(this);
-
- EventBus.getDefault().register(this);
- }
- SessionThread thread;
-
- @Subscribe(threadMode = ThreadMode.MAIN)
- public synchronized void MessageEventBusa(MessageEvent messageEvent) {
- String string = messageEvent.getString();
- switch (messageEvent.getCode()) {
- case 1://
- textView.setText(string);
- break;
- case 2:
- addText(string);
- case 505:
- if (isClient) {
- return;
- }
- textView.setText(string);
- ++index;
- thread=null;
- thread = new SessionThread();
- thread.start();
- // executorService.execute(thread);
- break;
- }
- }
-
- private void addText(String string) {
- TextView textView = new TextView(this);
- LinearLayout.LayoutParams lllp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- textView.setText(string);
- linearLayout.addView(textView, lllp);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- EventBus.getDefault().unregister(this);
- }
-
-
- /* 发送进程 */
- private class SessionThread extends Thread {
- @Override
- public void run() {
-
- synchronized (this) {
- Log.e("wifiInfo", "index="+index);
- if (index > 255) {
- return;
- }
- try {
- String ipStart = "", ipEnd = "";
- //获取wifi服务
- WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
- if (wifiManager != null) {
- if (!wifiManager.isWifiEnabled())
- wifiManager.setWifiEnabled(true);
-
- WifiInfo wifiInfo = wifiManager.getConnectionInfo();
- int ipAddress = wifiInfo.getIpAddress();
- String str = intToIp(ipAddress);
- String[] ip = str.split("\\.");
- if (ip.length == 4) {
- ipStart = (ip[0] + "." + ip[1] + "." + ip[2] + ".2");
- ipEnd = (ip[0] + "." + ip[1] + "." + ip[2] + ".255");
- }
- }
- Log.e("wifiInfo", "startIP=" + ipStart);
- String[] startStr = ipStart.split("\\.");
- String[] endStr = ipEnd.split("\\.");
-
- // 扫描设备
- int startInt = Integer.parseInt(startStr[3]);
- int endInt = Integer.parseInt(endStr[3]);
-
- if (startStr.length == endStr.length && startStr[0].equals(endStr[0]) && startStr[1].equals(endStr[1]) && startStr[2].equals(endStr[2])) {
- int num = endInt - startInt;
- if (num > -1) {
-
- WebSocketClient[] websocket = new WebSocketClient[endInt - startInt + 1];
- String ipAddress = startStr[0] + "." + startStr[1] + "." + startStr[2] + ".";
- Log.e("wifiInfo", "ipAddress=" + ipAddress);
- String ipServer = ipAddress + index;
- WebSocketClient.connect(ipServer);
- Log.e("wifiInfo", "ipServer=" + ipServer);
- }
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
- }
-
- }
-
- private String intToIp(int i) {
- return (i & 0xFF) + "." +
- ((i >> 8) & 0xFF) + "." +
- ((i >> 16) & 0xFF) + "." +
- (i >> 24 & 0xFF);
- }
- }

xml
- <?xml version="1.0" encoding="utf-8"?>
- <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
-
- <Button
- android:id="@+id/ready"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:text="等待连接"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintHorizontal_bias="0.359"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="0.011" />
-
- <Button
- android:id="@+id/connect"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="发起连接"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintHorizontal_bias="0.049"
- app:layout_constraintLeft_toLeftOf="parent"
- app:layout_constraintRight_toRightOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="0.023" />
-
- <TextView
- android:id="@+id/TextView2"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:layout_marginTop="8dp"
- android:text="连接到xxx"
- app:layout_constraintTop_toBottomOf="@+id/ready">
-
- </TextView>
- <LinearLayout
- android:id="@+id/linearLayout"
- android:layout_width="match_parent"
- android:layout_height="300dp"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
- android:orientation="vertical"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/TextView2"
- app:layout_constraintVertical_bias="0.0"
- tools:layout_editor_absoluteX="0dp">
- </LinearLayout>
-
- <EditText
- android:singleLine="true"
- android:id="@+id/editText"
- android:layout_width="match_parent"
- android:layout_height="100dp"
- android:layout_marginTop="8dp"
- app:layout_constraintTop_toBottomOf="@+id/linearLayout"
- tools:layout_editor_absoluteX="16dp" />
-
- <Button
- android:id="@+id/send"
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:layout_marginTop="8dp"
- app:layout_constraintTop_toBottomOf="@+id/editText"
- android:text="发送"
- tools:layout_editor_absoluteX="0dp" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。