Android Wifi热点 数据传输Socket 通信

0
回复
167
查看
[复制链接]

361

主题

366

帖子

7964

安币

手工艺人

发表于 2019-5-15 10:25:01 | 显示全部楼层 |阅读模式
如果对本篇文章感兴趣,请前往,原文地址:http://www.apkbus.com/blog-822719-80062.html

首先,描述下功能,两个手机,其中一个手机开热点,另外一个手机连接热点,2个手机间数据通信(不需要流量)。简述一下原理:开热点的手机相当于路由器,连接的手机作为客户端,获取路由器的IP建立Socket 连接,开始双方通信。![图片描述](/data/attachment/album/201905/15/102044isrhyv6yv5vc27ri.JPG)![图片描述](/data/attachment/album/201905/15/102049lh5avd22jh7gtazy.JPG)## 一、服务器端:开热点的作为服务器端初始化数据:```    public static final int DEVICE_CONNECTING = 1;//有设备正在连接热点    public static final int DEVICE_CONNECTED  = 2;//有设备连上热点    public static final int SEND_MSG_SUCCSEE  = 3;//发送消息成功    public static final int SEND_MSG_ERROR    = 4;//发送消息失败    public static final int GET_MSG           = 6;//获取新消息    private TextView      text_state;    private WifiManager   wifiManager;    /**     * 连接线程     */    private ConnectThread connectThread;    /**     * 监听线程     */    private ListenerThread listenerThread;    /**     * 热点名称     */    private static final String WIFI_HOTSPOT_SSID = "TEST";    /**     * 端口号     */    private static final int    PORT  = 54321;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        findViewById(R.id.create_wifi).setOnClickListener(this);        findViewById(R.id.close_wifi).setOnClickListener(this);        findViewById(R.id.send).setOnClickListener(this);        text_state = (TextView) findViewById(R.id.receive);        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);        /**         * 先开启监听线程,在开启连接         */        listenerThread = new ListenerThread(PORT, handler);        listenerThread.start();        try {Thread.sleep(1000);        } catch (InterruptedException e) {e.printStackTrace();        }        //        开启连接线程        new Thread(new Runnable() {@Overridepublic void run() {    try {        Log.i("ip", "getWifiApIpAddress()"   getWifiApIpAddress());        //本地路由开启通信        String ip = getWifiApIpAddress();        if (ip != null) {        } else {ip = "192.168.43.1";        }        Socket socket = new Socket(ip, PORT);        connectThread = new ConnectThread(MainActivity.this, socket, handler);        connectThread.start();    } catch (IOException e) {        e.printStackTrace();        runOnUiThread(new Runnable() {@Overridepublic void run() {    text_state.setText("创建通信失败");}        });    }}        }).start();    }```创建wifi 热点,之后开启Socket 监听线程``` /**     * 创建Wifi热点     */    private void createWifiHotspot() {        if (wifiManager.isWifiEnabled()) {//如果wifi处于打开状态,则关闭wifi,wifiManager.setWifiEnabled(false);        }        final WifiConfiguration config = new WifiConfiguration();        config.SSID = WIFI_HOTSPOT_SSID;        config.preSharedKey = "123456789";        config.hiddenSSID = false;        config.allowedAuthAlgorithms    .set(WifiConfiguration.AuthAlgorithm.OPEN);//开放系统认证        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);        config.allowedPairwiseCiphers    .set(WifiConfiguration.PairwiseCipher.TKIP);        config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);        config.allowedPairwiseCiphers    .set(WifiConfiguration.PairwiseCipher.CCMP);        config.status = WifiConfiguration.Status.ENABLED;        //通过反射调用设置热点        //192.168.43.59        //        Log.i("ip", "getWifiApIpAddress()"   getWifiApIpAddress()          //    "\n");        try {Method method = wifiManager.getClass().getMethod(        "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);boolean enable = (Boolean) method.invoke(wifiManager, config, true);if (enable) {    text_state.setText("热点已开启 SSID:"   WIFI_HOTSPOT_SSID   " password:123456789");    //        开启连接线程    new Thread(new Runnable() {        @Override        public void run() {try {    Log.i("ip", "getWifiApIpAddress()"   getWifiApIpAddress()    );    String ip = getWifiApIpAddress();    if (ip != null) {    } else {        //一般Android手机默认路由是        ip = "192.168.43.1";    }    //本地路由开启通信    Socket socket = new Socket(ip, PORT);    connectThread = new ConnectThread(MainActivity.this, socket, handler);    connectThread.start();} catch (IOException e) {    e.printStackTrace();    runOnUiThread(new Runnable() {        @Override        public void run() {text_state.setText("创建通信失败");        }    });}        }    }).start();    Thread.sleep(1000);    //    listenerThread = new ListenerThread(PORT, handler);    //    listenerThread.start();} else {    text_state.setText("创建热点失败");}        } catch (Exception e) {e.printStackTrace();text_state.setText("创建热点失败");        }    }```服务器端获取本地路由:```   public String getWifiApIpAddress() {        try {for (Enumeration en = NetworkInterface        .getNetworkInterfaces(); en.hasMoreElements(); ) {    NetworkInterface intf = en.nextElement();    if (intf.getName().contains("wlan")) {        for (Enumeration enumIpAddr = intf    .getInetAddresses(); enumIpAddr.hasMoreElements(); ) {InetAddress inetAddress = enumIpAddr.nextElement();if (!inetAddress.isLoopbackAddress()        && (inetAddress.getAddress().length == 4)) {    Log.d("Main", inetAddress.getHostAddress());    return inetAddress.getHostAddress();}        }    }}        } catch (SocketException ex) {Log.e("Main", ex.toString());        }        return null;    }```关闭热点``` /**     * 关闭WiFi热点     */    public void closeWifiHotspot() {        try {Method method = wifiManager.getClass().getMethod("getWifiApConfiguration");method.setAccessible(true);WifiConfiguration config = (WifiConfiguration) method.invoke(wifiManager);Method method2 = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);method2.invoke(wifiManager, config, false);        } catch (NoSuchMethodException e) {e.printStackTrace();        } catch (IllegalArgumentException e) {e.printStackTrace();        } catch (IllegalAccessException e) {e.printStackTrace();        } catch (InvocationTargetException e) {e.printStackTrace();        }        text_state.setText("热点已关闭");    }```ListenerThread 监听线程```import android.os.Handler;import android.os.Message;import android.util.Log;import com.example.syhuang.wifiserver.MainActivity;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;/** * 监听线程 * Created by syh on 2018/4/3 */public class ListenerThread extends Thread {    private ServerSocket serverSocket = null;    private Handler handler;    private int     port;    private Socket  socket;    public ListenerThread(int port, Handler handler) {        setName("ListenerThread");        this.port = port;        this.handler = handler;        try {serverSocket = new ServerSocket(port);//监听本机的12345端口        } catch (IOException e) {e.printStackTrace();        }    }    @Override    public void run() {        while (true) {try {    Log.i("ListennerThread", "阻塞");    //阻塞,等待设备连接    if (serverSocket != null)        socket = serverSocket.accept();    Message message = Message.obtain();    message.what = MainActivity.DEVICE_CONNECTING;    handler.sendMessage(message);} catch (IOException e) {    Log.i("ListennerThread", "error:"   e.getMessage());    e.printStackTrace();}        }    }    public Socket getSocket() {        return socket;    }}```ConnectThread 连接线程```package com.example.syhuang.wifiserver.thread;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import com.example.syhuang.wifiserver.MainActivity;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.text.DecimalFormat;/** * 连接线程 * Created by syhuang on 2018/4/3 */public class ConnectThread extends Thread {    private final Socket       socket;    private       Handler      handler;    private       InputStream  inputStream;    private       OutputStream outputStream;    Context context;    public ConnectThread(Context context, Socket socket, Handler handler) {        setName("ConnectThread");        Log.i("ConnectThread", "ConnectThread");        this.socket = socket;        this.handler = handler;        this.context = context;    }    @Override    public void run() {/*        if(activeConnect){//socket.c        }*/        if (socket == null) {return;        }        handler.sendEmptyMessage(MainActivity.DEVICE_CONNECTED);        try {//获取数据流inputStream = socket.getInputStream();outputStream = socket.getOutputStream();byte[] buffer = new byte[1024];int bytes;while (true) {    //读取数据    bytes = inputStream.read(buffer);    if (bytes > 0) {        final byte[] data = new byte[bytes];        System.arraycopy(buffer, 0, data, 0, bytes);        Message message = Message.obtain();        message.what = MainActivity.GET_MSG;        Bundle bundle = new Bundle();        bundle.putString("MSG", new String(data));        message.setData(bundle);        handler.sendMessage(message);    }    //    DataInputStream dis = null;    //    FileOutputStream fos = null;    //    try {    //        dis = new DataInputStream(inputStream);    //    //        // 文件名和长度    //        String fileName = dis.readUTF();    //        if (!fileName.equals("")) {    //long fileLength = dis.readLong();    //Log.i("ConnectThread", "======== 文件接收 [File Name:"   fileName   "] "      //        "[Size:"   getFormatFileSize(fileLength)   "] ========");    //File directory = new File(Environment.getExternalStorageDirectory()   "/");    //if (!directory.exists()) {    //    directory.mkdir();    //} else {    //}    //File file = new File(directory.getAbsolutePath()   File.separatorChar   fileName);    //fos = new FileOutputStream(file);    //    //// 开始接收文件    //byte[] bytesA = new byte[1024];    //int length = 0;    //int progress = 0;    //while ((length = dis.read(bytesA, 0, bytesA.length)) != -1) {    //    Log.i("ConnectThread", length   "...");    //    fos.write(bytesA, 0, length);    //    fos.flush();    //    progress  = length;    //    Log.i("ConnectThread", "| "   (100 * progress / file.length())   "% |");    //}    //Log.i("ConnectThread", "文件传输完成");    //    //Message message = Message.obtain();    //message.what = MainActivity.GET_MSG;    //Bundle bundle = new Bundle();    //bundle.putString("MSG", new String("接收到文件:"   file.getAbsolutePath()));    //message.setData(bundle);    //handler.sendMessage(message);    //        } else {    ////读取数据    //bytes = inputStream.read(buffer);    //if (bytes > 0) {    //    final byte[] data = new byte[bytes];    //    System.arraycopy(buffer, 0, data, 0, bytes);    //    //    //    Message message = Message.obtain();    //    message.what = MainActivity.GET_MSG;    //    Bundle bundle = new Bundle();    //    bundle.putString("MSG", new String(data));    //    message.setData(bundle);    //    handler.sendMessage(message);    //    //    Log.i("ConnectThread", "读取到数据:"   new String(data));    //}    //        }}        } catch (IOException e) {e.printStackTrace();        }    }    /**     * 格式化文件大小     *     * @param length     * @return     */    private String getFormatFileSize(long length) {        DecimalFormat df = new DecimalFormat("#0.0");        double size = ((double) length) / (1 = 1) {return df.format(size)   "GB";        }        size = ((double) length) / (1 = 1) {return df.format(size)   "MB";        }        size = ((double) length) / (1 = 1) {return df.format(size)   "KB";        }        return length   "B";    }    public static boolean copyFile(InputStream inputStream, OutputStream out) {        byte buf[] = new byte[1024];        int len;        try {while ((len = inputStream.read(buf)) != -1) {    out.write(buf, 0, len);}out.close();//inputStream.close();        } catch (IOException e) {return false;        }        return true;    }    /**     * 发送数据     */    public void sendData(String msg) {        Log.i("ConnectThread", "发送数据:"   (outputStream == null));        if (outputStream != null) {try {    outputStream.write(msg.getBytes());    Log.i("ConnectThread", "发送消息:"   msg);    Message message = Message.obtain();    message.what = MainActivity.SEND_MSG_SUCCSEE;    Bundle bundle = new Bundle();    bundle.putString("MSG", new String(msg));    message.setData(bundle);    handler.sendMessage(message);} catch (IOException e) {    e.printStackTrace();    Message message = Message.obtain();    message.what = MainActivity.SEND_MSG_ERROR;    Bundle bundle = new Bundle();    bundle.putString("MSG", new String(msg));    message.setData(bundle);    handler.sendMessage(message);}        }    }}```## 二、客户端客户端连接到热点,代码差不多,初始化数据部分顺序不一样,先开启连接线程,在开启监听线程,获取路由器IP 地址有差别。其他基本一样。wifi获取 已连接网络路由  路由ip地址```    /**     * wifi获取 已连接网络路由  路由ip地址     * @param context     * @return     */    private static String getWifiRouteIPAddress(Context context) {        WifiManager wifi_service = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);        DhcpInfo dhcpInfo = wifi_service.getDhcpInfo();        //        WifiInfo wifiinfo = wifi_service.getConnectionInfo();        //        System.out.println("Wifi info----->"   wifiinfo.getIpAddress());        //        System.out.println("DHCP info gateway----->"   Formatter.formatIpAddress(dhcpInfo.gateway));        //        System.out.println("DHCP info netmask----->"   Formatter.formatIpAddress(dhcpInfo.netmask));        //DhcpInfo中的ipAddress是一个int型的变量,通过Formatter将其转化为字符串IP地址        String routeIp = Formatter.formatIpAddress(dhcpInfo.gateway);        Log.i("route ip", "wifi route ip:"   routeIp);        return routeIp;    }```初始化``` public static final int DEVICE_CONNECTING = 1;//有设备正在连接热点    public static final int DEVICE_CONNECTED  = 2;//有设备连上热点    public static final int SEND_MSG_SUCCSEE  = 3;//发送消息成功    public static final int SEND_MSG_ERROR    = 4;//发送消息失败    public static final int GET_MSG           = 6;//获取新消息    private TextView      text_state;    /**     * 连接线程     */    private ConnectThread connectThread;    /**     * 监听线程     */    private ListenerThread listenerThread;    /**     * 热点名称     */    private static final String WIFI_HOTSPOT_SSID = "TEST";    /**     * 端口号     */    private static final int    PORT  = 54321;    private WifiManager wifiManager;    private TextView status_init;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        findViewById(R.id.send).setOnClickListener(this);        findViewById(R.id.connect).setOnClickListener(this);        findViewById(R.id.fileButton).setOnClickListener(this);        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);        //检查Wifi状态        if (!wifiManager.isWifiEnabled())wifiManager.setWifiEnabled(true);        text_state = (TextView) findViewById(R.id.status_info);        status_init = (TextView) findViewById(R.id.status_init);        status_init.setText("已连接到:"   wifiManager.getConnectionInfo().getSSID()      "\nIP:"   getIp()      "\n路由:"   getWifiRouteIPAddress(MainActivity.this));        //        initBroadcastReceiver();        //        开启连接线程        new Thread(new Runnable() {@Overridepublic void run() {    try {        Socket socket = new Socket(getWifiRouteIPAddress(MainActivity.this), PORT);        connectThread = new ConnectThread(socket, handler);        connectThread.start();    } catch (IOException e) {        e.printStackTrace();        runOnUiThread(new Runnable() {@Overridepublic void run() {    text_state.setText("通信连接失败");}        });    }}        }).start();        listenerThread = new ListenerThread(PORT, handler);        listenerThread.start();    }```服务器和客户端Handler处理一样```  private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {switch (msg.what) {    case DEVICE_CONNECTING:        connectThread = new ConnectThread(listenerThread.getSocket(), handler);        connectThread.start();        break;    case DEVICE_CONNECTED:        text_state.setText("设备连接成功");        break;    case SEND_MSG_SUCCSEE:        text_state.setText("发送消息成功:"   msg.getData().getString("MSG"));        break;    case SEND_MSG_ERROR:        text_state.setText("发送消息失败:"   msg.getData().getString("MSG"));        break;    case GET_MSG:        text_state.setText("收到消息:"   msg.getData().getString("MSG"));        break;}        }    };```源码传送门:http://www.apkbus.com/thread-607116-1-1.html  继续阅读全文



想在安卓巴士找到更多优质博文,可移步博客区

如果对本篇文章感兴趣,请前往,
原文地址:
http://www.apkbus.com/blog-822719-80062.html
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )