安卓Socket使用之服务器端

来源:互联网 发布:金数据 - 登录 编辑:程序博客网 时间:2024/05/18 00:45

MainActivity.java:

package itant.com.wifiserver;import android.content.Context;import android.net.wifi.WifiConfiguration;import android.net.wifi.WifiManager;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.TextView;import android.widget.Toast;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.StringBufferInputStream;import java.lang.reflect.Method;import java.net.ServerSocket;import java.net.Socket;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private TextView tv_status;    private TextView tv_content;    private boolean isClientConnected;    private static final int CLIENT_DISCONNECTED = 0;    private static final int CLIENT_CONNECTED = 1;    private static final int HOT_SPOT_READY = 2;    private static final int MSG_FROM_CLIENT = 3;    private WifiManager mWifiManager;    private Handler mServerHandler = new Handler(new Handler.Callback() {        @Override        public boolean handleMessage(Message msg) {            // TODO Auto-generated method stub            switch (msg.what) {                case CLIENT_DISCONNECTED:                    // 断开                    isClientConnected = false;                    break;                case CLIENT_CONNECTED:                    // 客户端连上了                    tv_status.setText("已连接");                    isClientConnected = true;                    break;                case HOT_SPOT_READY:                    // 热点创建成功,开启socket服务器端,监听客户端连接(监听断开)                    new ServerThread().start();                    break;                case MSG_FROM_CLIENT:                    if (msg.obj != null) {                        tv_content.setText(msg.obj.toString());                    } else {                        tv_content.setText("null" + System.currentTimeMillis());                    }                    break;                default:                    break;            }            return true;        }    });    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);        tv_status  = (TextView) findViewById(R.id.tv_status);        tv_content  = (TextView) findViewById(R.id.tv_content);        findViewById(R.id.btn_create_wifi).setOnClickListener(this);        findViewById(R.id.btn_send).setOnClickListener(this);    }    private void createWIFI(String hotSpotName, String password) {        if (mWifiManager.isWifiEnabled()) {            // 如果开启了WIFI,则将它关闭            mWifiManager.setWifiEnabled(false);        }        try{            WifiConfiguration wifiConfiguration = new WifiConfiguration();            //热点名称            wifiConfiguration.SSID = hotSpotName;            //热点密码            wifiConfiguration.preSharedKey = password;            wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);            wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);            wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);            wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);            wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);            wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);            wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);            wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);            // 利用反射获取开启热点的方法创建热点            HttpTools.setWifiApEnabled(mWifiManager, wifiConfiguration, true);            final Method isHotSpotEnable = mWifiManager.getClass().getMethod("isWifiApEnabled");            // 每隔1.5秒查看热点是否创建成功            new Thread(new Runnable() {                @Override                public void run() {                    // TODO Auto-generated method stub                    while (true) {                        try {                            boolean hotSpotEnable = (boolean) isHotSpotEnable.invoke(mWifiManager);                            if (hotSpotEnable) {                                mServerHandler.sendEmptyMessage(HOT_SPOT_READY);                                break;                            }                            Thread.sleep(1500);                        } catch (Exception e) {                            // TODO: handle exception                        }                    }                }            }).start();        }catch(Exception e){            e.printStackTrace();        }    }    private ServerSocket mServerSocket;    private boolean mIsServiceDestoryed = false;    /**往客户端发送文件的入口**/    private DataOutputStream mOutputStream;    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.btn_create_wifi:                // 创建热点                String hotSpotName = "backup" + System.currentTimeMillis();                String password = "away6899";                createWIFI(hotSpotName, password);                break;            case R.id.btn_send:                if (!isClientConnected) {                    Toast.makeText(this, "等待连接", Toast.LENGTH_SHORT).show();                    return;                }                // 发送信息                String str = "hello moto";                try {                    // 把文件名告诉客户端                    //mOutputStream.writeUTF(app.getAppName() + ".apk");                    //mOutputStream.flush();                    byte[] strBytes = str.getBytes("UTF-8");                    // 把长度诉客户端,否则不知道一个文件结尾在哪。千万不要直接传str.length()!!!因为我们采用的                    // 是UTF-8编码,其长度是有所区别的,如果直接传str.length()很可能会导致传递的数据不完整!                    mOutputStream.writeLong(strBytes.length);                    mOutputStream.flush();                    DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(strBytes));                    byte buf[] = new byte[1024];                    int len = -1;                    while ((len = inputStream.read(buf)) != -1) {                        mOutputStream.write(buf, 0, len);                    }                    mOutputStream.flush();                    inputStream.close();                    // 发送结束了                } catch (IOException e1) {                    e1.printStackTrace();                }                Toast.makeText(this, "发送完毕", Toast.LENGTH_SHORT).show();                break;        }    }    /**     * Socket服务器端     * @author 詹子聪     */    private class ServerThread extends Thread {        @Override        public void run() {            try {                mServerSocket = new ServerSocket(8688);            } catch (IOException e) {                System.err.println("establish tcp server failed, port:8688");                e.printStackTrace();                return;            }            while (!Thread.currentThread().isInterrupted()) {                try {                    // 一个客户端连接上了                    final Socket mClient = mServerSocket.accept();                    mOutputStream = new DataOutputStream(mClient.getOutputStream());                    mServerHandler.sendEmptyMessage(CLIENT_CONNECTED);                    CommunicationThread commThread = new CommunicationThread(mClient);                    new Thread(commThread).start();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    @Override    protected void onDestroy() {        super.onDestroy();        mIsServiceDestoryed = true;        // 关闭流        if (mServerSocket != null) {            try {                if (mOutputStream != null) {                    mOutputStream.close();                }                mServerSocket.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    class CommunicationThread implements Runnable {        private Socket clientSocket;        private BufferedReader input;        public CommunicationThread(Socket clientSocket) {            this.clientSocket = clientSocket;            try {                this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));            } catch (IOException e) {                e.printStackTrace();            }        }        public void run() {            while (!Thread.currentThread().isInterrupted()) {                /*try {                    String read = input.readLine();                    System.out.println("获取到客户端的信息:" + read);                    Message message = Message.obtain();                    message.what = MSG_FROM_CLIENT;                    message.obj = read;                    mServerHandler.sendMessage(message);                } catch (IOException e) {                    e.printStackTrace();                }*/                try {                    // 接收客户端的消息和文件                    DataInputStream inputStream = new DataInputStream(new BufferedInputStream(this.clientSocket.getInputStream()));                    // 不断地监听,看客户端是否有东西过来                    while (!MainActivity.this.isFinishing()) {                        //String fileName = inputStream.readUTF();                        long fileSize = inputStream.readLong();                        ByteArrayOutputStream out = new ByteArrayOutputStream();                        DataOutputStream outputStream = new DataOutputStream(                                new BufferedOutputStream(out));                        byte[] buffer = new byte[(int) fileSize];                        int nIdx = 0;                        int nTotalLen = buffer.length;                        int nReadLen = 0;                        while (nIdx < nTotalLen) {                            // 从nIdx开始,想读nTotalLen - nIdx那么多,实际上这次读了nReadLen                            nReadLen = inputStream.read(buffer, nIdx, nTotalLen - nIdx);                            if (nReadLen > 0) {                                outputStream.write(buffer, nIdx, nReadLen);                                nIdx = nIdx + nReadLen;                            } else {                                break;                            }                        }                        outputStream.close();                        String str = out.toString();                        Message message = Message.obtain();                        message.obj = str;                        message.what = MSG_FROM_CLIENT;                        mServerHandler.sendMessage(message);                    }                    System.out.println("quit...");                    this.clientSocket.close();                } catch (Exception e) {                    e.printStackTrace();                }            }        }    }}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <TextView        android:id="@+id/tv_status"        android:text="未连接"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/tv_content"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <Button        android:id="@+id/btn_create_wifi"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="创建热点"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toTopOf="parent" />    <Button        android:id="@+id/btn_send"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="发送信息"        android:layout_marginTop="16dp"/></LinearLayout>

清单文件:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="itant.com.wifiserver">    <uses-permission android:name="android.permission.INTERNET"/>    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.READ_PHONE_STATE" />    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />    <!-- 文件存储 -->    <uses-permission android:name="android.permission.WAKE_LOCK" />    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

HttpTools.java(和客户端的一样):

package itant.com.wifiserver;import android.content.Context;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.net.wifi.WifiConfiguration;import android.net.wifi.WifiManager;import android.text.format.Formatter;import java.lang.reflect.Method;/** * 网络请求相关辅助类 * @author jason.zhan * */public class HttpTools {    /**     * 判断是否有网络     * @param context     * @return     */    public static boolean isNetworkConnected(Context context) {        if (context != null) {              ConnectivityManager mConnectivityManager = (ConnectivityManager) context                    .getSystemService(Context.CONNECTIVITY_SERVICE);            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();            if (mNetworkInfo != null) {                  return mNetworkInfo.isAvailable();              }          }          return false;      }    public static boolean setWifiApEnabled(WifiManager wifiManager, WifiConfiguration wifiConfiguration, boolean enable) {        boolean invokeStatus = true;        try {            Method setupHotSpot = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);            setupHotSpot.invoke(wifiManager, wifiConfiguration, enable);        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();            invokeStatus = false;        }        return invokeStatus;    }    /**     * 判断WiFi是否连接上了     * @param context     * @return     */    public static boolean isWiFiConnected(Context context) {        if (context != null) {              ConnectivityManager mConnectivityManager = (ConnectivityManager) context                    .getSystemService(Context.CONNECTIVITY_SERVICE);            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();            if (mNetworkInfo != null) {                return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);            }          }          return false;      }    /**     * 获取所连接的WiFi名称     * @param wifiManager     * @return     */    public static String getConnectedWifiSsid(WifiManager wifiManager) {        return wifiManager.getConnectionInfo().getSSID();      }      /**     * @return (发送端)服务器IP地址,转换IP输出格式     */    public static String getSenderIP(WifiManager wifiManager) {        //WifiInfo wifiInfo = wifiManager.getConnectionInfo();        //int ipAddress = wifiInfo.getIpAddress();          int ipAddress = wifiManager.getDhcpInfo().serverAddress;        return Formatter.formatIpAddress(ipAddress);    }    /*****************************供接收者使用***************************************/    // 加密类型,分为三种情况:1.没有密码   2.用WEP加密    3.用WPA加密,我们这里只用到了第3种    public static final int TYPE_NO_PASSWD = 1;    public static final int TYPE_WEP = 2;    public static final int TYPE_WPA = 3;    /**     * 连接信息生成配置对象     */    public static WifiConfiguration createWifiInfo(String SSID, String password, int type) {        WifiConfiguration config = new WifiConfiguration();        config.SSID = SSID;        // 清除热点记录clearAll(SSID);        if (type == TYPE_NO_PASSWD) {            config.hiddenSSID = false;            config.status = WifiConfiguration.Status.ENABLED;            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);            config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);            config.preSharedKey = null;        } else if (type == TYPE_WEP) {            config.hiddenSSID = true;            config.wepKeys[0] = "\"" + password + "\"";            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);            config.wepTxKeyIndex = 0;        } else if (type == TYPE_WPA) {            config.preSharedKey = "\"" + password + "\"";            config.hiddenSSID = false;            config.priority = 10000;            config.status = WifiConfiguration.Status.ENABLED;            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);            config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);        }        return config;    }    /*****************************供接收者使用***************************************/}
原创粉丝点击