0
点赞
收藏
分享

微信扫一扫

C++17之std::invoke: 使用和原理探究(全)

我是小瘦子哟 03-08 17:00 阅读 2

废话不多说直接上代码

//权限 引入
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!--允许应用程序改变网络状态-->
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <!--允许应用程序改变WIFI连接状态-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <!--允许应用程序访问有关的网络信息-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!--允许应用程序访问WIFI网卡的网络信息-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <!--允许应用程序完全使用网络-->
    <uses-permission android:name="android.permission.INTERNET"/>

获取当前ip地址



import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

public class NetWorkUtil {
    public static String getIPAddress(Context context) {
        NetworkInfo info = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
        if (info != null && info.isConnected()) {
            if (info.getType() == ConnectivityManager.TYPE_MOBILE) {//当前使用2G/3G/4G网络
                try {
                    //Enumeration<NetworkInterface> en=NetworkInterface.getNetworkInterfaces();
                    for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                        NetworkInterface intf = en.nextElement();
                        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                            InetAddress inetAddress = enumIpAddr.nextElement();
                            if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                                return inetAddress.getHostAddress();
                            }
                        }
                    }
                } catch (SocketException e) {
                    e.printStackTrace();
                }

            } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {//当前使用无线网络
                WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
                WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                String ipAddress = intIP2StringIP(wifiInfo.getIpAddress());//得到IPV4地址
                return ipAddress;
            }
        } else {
            //当前无网络连接,请在设置中打开网络
        }
        return null;
    }

    /**
     * 将得到的int类型的IP转换为String类型
     *
     * @param ip
     * @return
     */
    public static String intIP2StringIP(int ip) {
        return (ip & 0xFF) + "." +
                ((ip >> 8) & 0xFF) + "." +
                ((ip >> 16) & 0xFF) + "." +
                (ip >> 24 & 0xFF);
    }


}

服务端



import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class TcpServerActivity extends Activity implements OnClickListener {
    private final String TAG = "TcpServerActivity";
    private TextView mServerState, mTvReceive;

    private TextView ipTextView = null;
    private TextView nameTextView = null;
    //定义一个ConnectivityManager对象
    private ConnectivityManager mConnectivityManager = null;
    //定义一个NetworkInfo对象
    private NetworkInfo mActiveNetInfo = null;



    private Button mBtnSet, mBtnStrat, mBtnSend;
    private EditText mEditMsg;
    private ServerSocket mServerSocket;
    public Socket mSocket;

    private SharedPreferences mSharedPreferences;
    private final int DEFAULT_PORT = 8086;
    private int mServerPort; //服务端端口

    private static final String SERVER_PORT = "server_port";
    private static final String SERVER_MESSAGETXT = "server_msgtxt";
    private OutputStream mOutStream;
    private InputStream mInStream;
    private SocketAcceptThread mAcceptThread;
    private SocketReceiveThread mReceiveThread;

    private HandlerThread mHandlerThread;
    //子线程中的Handler实例。
    private Handler mSubThreadHandler;

    private final int STATE_CLOSED = 1;
    private final int STATE_ACCEPTING= 2;
    private final int STATE_CONNECTED = 3;
    private final int STATE_DISCONNECTED = 4;

    private int mSocketConnectState = STATE_CLOSED;

    private String mRecycleMsg;
    private static final int MSG_TIME_SEND = 1;
    private static final int MSG_SOCKET_CONNECT = 2;
    private static final int MSG_SOCKET_DISCONNECT = 3;
    private static final int MSG_SOCKET_ACCEPTFAIL = 4;
    private static final int MSG_RECEIVE_DATA = 5;
    private static final int MSG_SEND_DATA = 6;
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler(){
        public void handleMessage(Message msg) {
            switch(msg.what){
                case MSG_TIME_SEND:
                    writeMsg(mRecycleMsg);
                    break;
                case MSG_SOCKET_CONNECT:
                    mSocketConnectState = STATE_CONNECTED;
                    mServerState.setText(R.string.state_connected);
                    mReceiveThread = new SocketReceiveThread();
                    mReceiveThread.start();
                    break;
                case MSG_SOCKET_DISCONNECT:
                    mSocketConnectState = STATE_DISCONNECTED;
                    mServerState.setText(R.string.state_disconect_accept);
                    startAccept();
                    break;
                case MSG_SOCKET_ACCEPTFAIL:
                    startAccept();
                    break;
                case MSG_RECEIVE_DATA:
                    String text = mTvReceive.getText().toString() +"\r\n" + (String)msg.obj;
                    mTvReceive.setText(text);
                    break;
                default:
                    break;
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tcp_server);
        mServerState = (TextView) findViewById(R.id.serverState);
        mBtnSet = (Button)findViewById(R.id.bt_server_set);
        mBtnStrat = (Button)findViewById(R.id.bt_server_start);
        mBtnSend = (Button)findViewById(R.id.bt_server_send);
        mEditMsg = (EditText)findViewById(R.id.server_sendMsg);
        mTvReceive = (TextView) findViewById(R.id.server_receive);

        ipTextView = (TextView)findViewById(R.id.ipTextView);

        ipTextView.setText(NetWorkUtil.getIPAddress(TcpServerActivity.this));

        mBtnSet.setOnClickListener(this);
        mBtnStrat.setOnClickListener(this);
        mBtnSend.setOnClickListener(this);
        mSharedPreferences = getSharedPreferences("setting", Context.MODE_PRIVATE);

        mServerPort = mSharedPreferences.getInt(SERVER_PORT, DEFAULT_PORT);

        initHandlerThraed();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(mSocketConnectState == STATE_CLOSED)
            mServerState.setText(R.string.state_closed);
        else if(mSocketConnectState == STATE_CONNECTED)
            mServerState.setText(R.string.state_connected);
        else if(mSocketConnectState == STATE_DISCONNECTED || mSocketConnectState == STATE_ACCEPTING)
            mServerState.setText(R.string.state_disconect_accept);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
        //退出HandlerThread的Looper循环。
        mHandlerThread.quit();
        closeConnect();
        if(mServerSocket != null){
            try {
                mServerSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.bt_server_set:
                set();
                break;
            case R.id.bt_server_start:
                startServer();
                break;
            case R.id.bt_server_send:
                sendTxt();
                break;
            default:
                break;
        }
    }

    private void set(){
        View setview = LayoutInflater.from(this).inflate(R.layout.dialog_server, null);
        final EditText editport = (EditText)setview.findViewById(R.id.server_port);
        Button ensureBtn = (Button)setview.findViewById(R.id.server_ok);

        editport.setText(mSharedPreferences.getInt(SERVER_PORT, 8086) + "");

        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setView(setview); //设置dialog显示一个view
        final AlertDialog dialog = builder.show(); //dialog显示
        ensureBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String port = editport.getText().toString();
                if(port != null && port.length() >0){
                    mServerPort = Integer.parseInt(port);
                }
                SharedPreferences.Editor editor=mSharedPreferences.edit();
                editor.putInt(SERVER_PORT, mServerPort);
                editor.commit();
                dialog.dismiss(); //dialog消失
            }
        });

    }
    private void startServer() {
        if(mSocketConnectState != STATE_CLOSED) return;
        try {
            //开启服务、指定端口号
            mServerSocket = new ServerSocket(mServerPort);
        } catch (IOException e) {
            e.printStackTrace();
            mSocketConnectState = STATE_DISCONNECTED;
            Toast.makeText(this, "服务开启失败", Toast.LENGTH_SHORT).show();
            return;
        }
        startAccept();
        mServerState.setText(getString(R.string.state_opened));
        Toast.makeText(this, "服务开启", Toast.LENGTH_SHORT).show();
    }
    private void startAccept(){
        mSocketConnectState = STATE_ACCEPTING;
        mAcceptThread = new SocketAcceptThread();
        mAcceptThread.start();
    }
    private void sendTxt(){
        if(mRecycleMsg != null){
            //每次点击发送按钮发送数据,将之前的定时发送移除。
            mHandler.removeMessages(MSG_TIME_SEND);
            mRecycleMsg = null;
        }
        if(mSocket == null){
            Toast.makeText(this, "没有客户端连接", Toast.LENGTH_SHORT).show();
            return;
        }
        String str = mEditMsg.getText().toString();
        if(str.length() == 0)
            return;
        Message msg = new Message();
        msg.what = MSG_SEND_DATA;
        msg.obj = str;
        mSubThreadHandler.sendMessage(msg);
    }

    private void writeMsg(String msg){
        if(msg.length() == 0 || mOutStream == null)
            return;
        try {
            mOutStream.write(msg.getBytes());//发送
            mOutStream.flush();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void closeConnect(){
        try {
            if (mOutStream != null) {
                mOutStream.close();
            }
            if (mInStream != null) {
                mInStream.close();
            }
            if(mSocket != null){
                mSocket.close();  //关闭socket
                mSocket = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(mReceiveThread != null){
            mReceiveThread.threadExit();
            mReceiveThread = null;
        }
    }

    class SocketAcceptThread extends Thread{
        @Override
        public void run() {
            try {
                //等待客户端的连接,Accept会阻塞,直到建立连接,
                //所以需要放在子线程中运行。
                mSocket = mServerSocket.accept();
                //获取输入流
                mInStream = mSocket.getInputStream();
                //获取输出流
                mOutStream = mSocket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
                mHandler.sendEmptyMessage(MSG_SOCKET_ACCEPTFAIL);
                return;
            }
            Log.i(TAG, "accept success");
            mHandler.sendEmptyMessage(MSG_SOCKET_CONNECT);
        }
    }
    class SocketReceiveThread extends Thread{
        private boolean threadExit = false;
        public void run(){
            byte[] buffer = new byte[1024];
            while(threadExit == false){
                try { //读取数据,返回值表示读到的数据长度。-1表示结束
                    int count = mInStream.read(buffer);
                    if(count == -1){
                        Log.i(TAG, "read read -1");
                        mHandler.sendEmptyMessage(MSG_SOCKET_DISCONNECT);
                        break;
                    }else{
                        String receiveData;
                        receiveData = new String(buffer, 0, count);
                        Log.i(TAG, "read buffer:"+receiveData+",count="+count);
                        Message msg = new Message();
                        msg.what = MSG_RECEIVE_DATA;
                        msg.obj = receiveData;
                        mHandler.sendMessage(msg);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        void threadExit(){
            threadExit = true;
        }
    }

    private void initHandlerThraed() {
        //创建HandlerThread实例
        mHandlerThread = new HandlerThread("handler_thread");
        //开始运行线程
        mHandlerThread.start();
        //获取HandlerThread线程中的Looper实例
        Looper loop = mHandlerThread.getLooper();
        //创建Handler与该线程绑定。
        mSubThreadHandler = new Handler(loop){
            public void handleMessage(Message msg) {
                Log.i(TAG, "mSubThreadHandler handleMessage thread:"+Thread.currentThread());
                switch(msg.what){
                    case MSG_SEND_DATA:
                        writeMsg((String)msg.obj);
                        break;
                    default:
                        break;
                }
            };
        };
    }
}

布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/server_lin"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
        <TextView
            android:id="@+id/serverState"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/layout_top_margin"
            android:gravity="center"
            android:text="@string/state"
            android:textSize="@dimen/title_size" />



        <LinearLayout
            android:layout_width="match_parent"
            android:orientation="horizontal"
            android:layout_marginLeft="20dp"
            android:layout_height="wrap_content">


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="本地IP地址:"/>


            <TextView

                android:id="@+id/ipTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=" "
                android:textSize="20dp"

                />




        </LinearLayout>

        <LinearLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:layout_marginTop="@dimen/layout_top_margin"
            android:layout_marginLeft="@dimen/left_right_margin"
            android:layout_marginRight="@dimen/left_right_margin"
            android:orientation="horizontal">
            <Button
                android:id="@+id/bt_server_set"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/set" />

            <Button
                android:id="@+id/bt_server_start"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/start_server" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/left_right_margin"
            android:layout_marginRight="@dimen/left_right_margin"
            android:orientation="horizontal">

            <EditText
                android:id="@+id/server_sendMsg"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:hint="@string/send_hint" />

            <Button android:id="@+id/bt_server_send"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/send"/>
        </LinearLayout>

        <View
            android:layout_width="match_parent"
            android:layout_height="0.2dp"
            android:background="#000"/>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="服务端返回信息如下:"/>
    </LinearLayout>
    <ScrollView
        android:id="@+id/server_scroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/server_lin"
        android:layout_alignParentBottom="true">




        <TextView
            android:id="@+id/server_receive"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/left_right_margin"
            android:layout_marginRight="@dimen/left_right_margin"

            android:textSize="20dp" />

    </ScrollView>
</RelativeLayout>

效果图

设置弹窗  dialog_server.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/port"
            android:textSize="@dimen/dialog_txt_size"/>
        <EditText
            android:id="@+id/server_port"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:inputType="number"
            android:digits="0123456789"
            android:ems="10"/>
    </LinearLayout>


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:visibility="gone" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/message_mode"
            android:gravity="center"
            android:layout_weight="1"
            android:textSize="@dimen/dialog_txt_size"/>

        <RadioGroup
            android:id="@+id/display_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:orientation="horizontal" >
            <RadioButton
                android:id="@+id/server_modetxt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="@string/txt" />
            <RadioButton
                android:id="@+id/server_modehex"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/hex" />
        </RadioGroup>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:visibility="gone" >
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/send_ontime" />

        <EditText
            android:id="@+id/server_timeinterval"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:inputType="number"
            android:digits="0123456789"
            android:ems="10"
            android:hint="@string/hint_time" >
        </EditText>
    </LinearLayout>

    <Button
        android:id="@+id/server_ok"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/ok" />
</LinearLayout>

效果

以上就socket服务端代码


下面就是客户端代码了



import android.os.Bundle;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class TcpClientActivity extends Activity implements View.OnClickListener {
    private final String TAG = "TcpClientActivity";
    private Button mBtnSet, mBtnConnect, mBtnSend;
    private EditText mEditMsg;
    private TextView mClientState, mTvReceive;
    public Socket mSocket;

    private SharedPreferences mSharedPreferences;
    private final int DEFAULT_PORT= 8086;
    private String mIpAddress;  //服务端ip地址
    private int mClientPort; //端口,默认为8086,可以进行设置
    private static final String IP_ADDRESS = "ip_address";
    private static final String CLIENT_PORT = "client_port";
    private static final String CLIENT_MESSAGETXT = "client_msgtxt";

    private OutputStream mOutStream;
    private InputStream mInStream;
    private SocketConnectThread mConnectThread;
    private SocketReceiveThread mReceiveThread;

    private HandlerThread mHandlerThread;
    //子线程中的Handler实例。
    private Handler mSubThreadHandler;

    private final int STATE_DISCONNECTED = 1;
    private final int STATE_CONNECTING= 2;
    private final int STATE_CONNECTED = 3;
    private int mSocketConnectState = STATE_DISCONNECTED;

    private static final int MSG_TIME_SEND = 1;
    private static final int MSG_SOCKET_CONNECT = 2;
    private static final int MSG_SOCKET_DISCONNECT = 3;
    private static final int MSG_SOCKET_CONNECTFAIL = 4;
    private static final int MSG_RECEIVE_DATA = 5;
    private static final int MSG_SEND_DATA = 6;
    private Handler mHandler = new Handler(){
        public void handleMessage(Message msg) {
            switch(msg.what){
                case MSG_TIME_SEND:
                    break;
                case MSG_SOCKET_CONNECT:
                    mSocketConnectState = STATE_CONNECTED;
                    mClientState.setText(R.string.state_connected);
                    mBtnConnect.setText(R.string.disconnect);
                    mReceiveThread = new SocketReceiveThread();
                    mReceiveThread.start();
                    break;
                case MSG_SOCKET_DISCONNECT:
                    mClientState.setText(R.string.state_disconected);
                    mBtnConnect.setText(R.string.connect);
                    mSocketConnectState = STATE_DISCONNECTED;
                    closeConnection();
                    break;
                case MSG_SOCKET_CONNECTFAIL:
                    mSocketConnectState = STATE_DISCONNECTED;
                    mBtnConnect.setText(R.string.connect);
                    mClientState.setText(R.string.state_connect_fail);
                    break;
                case MSG_RECEIVE_DATA:
                    String text = mTvReceive.getText().toString() +"\r\n" + (String)msg.obj;
                    mTvReceive.setText(text);
                    break;
                default:
                    break;
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tcp_client);
        mBtnSet = (Button)findViewById(R.id.bt_client_set);
        mBtnConnect = (Button)findViewById(R.id.bt_client_connect);
        mBtnSend = (Button)findViewById(R.id.bt_client_send);
        mEditMsg = (EditText)findViewById(R.id.client_sendMsg);
        mClientState = (TextView) findViewById(R.id.client_state);
        mTvReceive = (TextView) findViewById(R.id.client_receive);
        mBtnSet.setOnClickListener(this);
        mBtnConnect.setOnClickListener(this);
        mBtnSend.setOnClickListener(this);
        mSharedPreferences = getSharedPreferences("setting", Context.MODE_PRIVATE);
        //获取保存的ip地址、客户端端口号
        mIpAddress = mSharedPreferences.getString(IP_ADDRESS, null);
        mClientPort = mSharedPreferences.getInt(CLIENT_PORT, DEFAULT_PORT);
        initHandlerThraed();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(mSocketConnectState == STATE_CONNECTED){
            mBtnConnect.setText(R.string.disconnect);
            mClientState.setText(R.string.state_connected);
        }else if(mSocketConnectState == STATE_DISCONNECTED){
            mBtnConnect.setText(R.string.connect);
            mClientState.setText(R.string.state_disconected);
        }
        else if(mSocketConnectState == STATE_CONNECTING){
            mClientState.setText(R.string.state_connecting);
            mClientState.setText(R.string.state_connected);
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //退出HandlerThread的Looper循环。
        mHandlerThread.quit();
        closeConnection();
    }
    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.bt_client_set:
                set();
                break;
            case R.id.bt_client_connect:
                if(mSocketConnectState == STATE_CONNECTED){
                    closeConnection();
                }else{
                    startConnect();
                }
                break;
            case R.id.bt_client_send:
                sendTxt();
                break;
            default:
                break;
        }
    }

    private void set(){
        View setview = LayoutInflater.from(this).inflate(R.layout.dialog_client, null);
        final EditText ipAddress = (EditText) setview.findViewById(R.id.edtt_ipaddress);
        final EditText editport = (EditText)setview.findViewById(R.id.client_port);
        Button ensureBtn = (Button)setview.findViewById(R.id.client_ok);

        ipAddress.setText(mSharedPreferences.getString(IP_ADDRESS, null));
        editport.setText(mSharedPreferences.getInt(CLIENT_PORT, 8086) + "");

        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setView(setview); //设置dialog显示一个view
        final AlertDialog dialog = builder.show(); //dialog显示
        ensureBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String port = editport.getText().toString();
                mIpAddress = ipAddress.getText().toString();
                if(port != null && port.length() >0){
                    mClientPort = Integer.parseInt(port);
                }
                SharedPreferences.Editor editor=mSharedPreferences.edit();
                editor.putString(IP_ADDRESS, mIpAddress);
                editor.putInt(CLIENT_PORT, mClientPort);
                editor.commit();
                dialog.dismiss(); //dialog消失
            }
        });

    }
    private void startConnect() {
        Log.i(TAG,"startConnect");
        if(mIpAddress == null || mIpAddress.length() == 0){
            Toast.makeText(this, "请设置ip地址", Toast.LENGTH_LONG).show();
            return;
        }
        if(mSocketConnectState != STATE_DISCONNECTED) return;
        mConnectThread = new SocketConnectThread();
        mConnectThread.start();
        mSocketConnectState = STATE_CONNECTING;
        mClientState.setText(R.string.state_connecting);
    }

    private void sendTxt(){
        if(mSocket == null){
            Toast.makeText(this, "没有连接", Toast.LENGTH_SHORT).show();
            return;
        }
        String str = mEditMsg.getText().toString();
        if(str.length() == 0)
            return;
        Message msg = new Message();
        msg.what = MSG_SEND_DATA;
        msg.obj = str;
        mSubThreadHandler.sendMessage(msg);
    }

    private void writeMsg(String msg){
        Log.i(TAG, "writeMsg msg="+msg);
        if(msg.length() == 0 || mOutStream == null)
            return;
        try {
            mOutStream.write(msg.getBytes());//发送
            mOutStream.flush();
        }catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void closeConnection(){
        try {
            if (mOutStream != null) {
                mOutStream.close(); //关闭输出流
                mOutStream = null;
            }
            if (mInStream != null) {
                mInStream.close(); //关闭输入流
                mInStream = null;
            }
            if(mSocket != null){
                mSocket.close();  //关闭socket
                mSocket = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(mReceiveThread != null){
            mReceiveThread.threadExit();
            mReceiveThread = null;
        }
        mSocketConnectState = STATE_DISCONNECTED;
        mBtnConnect.setText(R.string.connect);
        mClientState.setText(R.string.state_disconected);
    }

    class SocketConnectThread extends Thread{
        public void run(){
            try {
                //连接服务端,指定服务端ip地址和端口号。
                mSocket = new Socket(mIpAddress,mClientPort);
                if(mSocket != null){
                    //获取输出流、输入流
                    mOutStream = mSocket.getOutputStream();
                    mInStream = mSocket.getInputStream();
                }
            } catch (Exception e) {
                e.printStackTrace();
                mHandler.sendEmptyMessage(MSG_SOCKET_CONNECTFAIL);
                return;
            }
            Log.i(TAG,"connect success");
            mHandler.sendEmptyMessage(MSG_SOCKET_CONNECT);
        }

    }
    class SocketReceiveThread extends Thread{
        private boolean threadExit;
        public SocketReceiveThread() {
            threadExit = false;
        }
        public void run(){
            byte[] buffer = new byte[1024];
            while(threadExit == false){
                try {
                    //读取数据,返回值表示读到的数据长度。-1表示结束
                    int count = mInStream.read(buffer);
                    if( count == -1){
                        Log.i(TAG, "read read -1");
                        mHandler.sendEmptyMessage(MSG_SOCKET_DISCONNECT);
                        break;
                    }else{
                        String receiveData = new String(buffer, 0, count);
                        Log.i(TAG, "read buffer:"+receiveData+",count="+count);
                        Message msg = new Message();
                        msg.what = MSG_RECEIVE_DATA;
                        msg.obj = receiveData;
                        mHandler.sendMessage(msg);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        void threadExit(){
            threadExit = true;
        }
    }

    private void initHandlerThraed() {
        //创建HandlerThread实例
        mHandlerThread = new HandlerThread("handler_thread");
        //开始运行线程
        mHandlerThread.start();
        //获取HandlerThread线程中的Looper实例
        Looper loop = mHandlerThread.getLooper();
        //创建Handler与该线程绑定。
        mSubThreadHandler = new Handler(loop){
            public void handleMessage(Message msg) {
                Log.i(TAG, "mSubThreadHandler handleMessage thread:"+Thread.currentThread());
                switch(msg.what){
                    case MSG_SEND_DATA:
                        writeMsg((String)msg.obj);
                        break;
                    default:
                        break;
                }
            };
        };
    }
}

布局代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/client_lin"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
        <TextView
            android:id="@+id/client_state"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_marginTop="@dimen/layout_top_margin"
            android:text="@string/state"
            android:textSize="@dimen/title_size" />

        <LinearLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:layout_marginTop="@dimen/layout_top_margin"
            android:layout_marginLeft="@dimen/left_right_margin"
            android:layout_marginRight="@dimen/left_right_margin"
            android:orientation="horizontal">
            <Button
                android:id="@+id/bt_client_set"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/set" />

            <Button
                android:id="@+id/bt_client_connect"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/connect" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/left_right_margin"
            android:layout_marginRight="@dimen/left_right_margin"
            android:orientation="horizontal">

            <EditText
                android:id="@+id/client_sendMsg"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:hint="@string/send_hint" />

            <Button android:id="@+id/bt_client_send"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@string/send"/>
        </LinearLayout>
    </LinearLayout>

    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/client_lin"
        android:layout_alignParentBottom="true">

        <TextView
            android:id="@+id/client_receive"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/left_right_margin"
            android:layout_marginRight="@dimen/left_right_margin"
            android:textSize="20sp" />
    </ScrollView>

</RelativeLayout>

效果

设置弹窗布局 dialog_client.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/server_ip"
            android:textSize="@dimen/dialog_txt_size"/>
        <EditText
            android:id="@+id/edtt_ipaddress"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:ems="10"
            android:hint="格式:10.10.4.11"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/port"
            android:textSize="@dimen/dialog_txt_size"/>
        <EditText
            android:id="@+id/client_port"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:inputType="number"
            android:hint="8086"
            android:digits="0123456789"
            android:ems="10"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:visibility="gone" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/message_mode"
            android:gravity="center"
            android:layout_weight="1"
            android:textSize="@dimen/dialog_txt_size"/>

        <RadioGroup
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="horizontal" >
            <RadioButton
                android:id="@+id/client_modetxt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="@string/txt" />
            <RadioButton
                android:id="@+id/client_modehex"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/hex" />
        </RadioGroup>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:visibility="gone" >
        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@string/send_ontime" />

        <EditText
            android:id="@+id/client_timeinterval"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:inputType="number"
            android:digits="0123456789"
            android:ems="10"
            android:hint="@string/hint_time" >
        </EditText>
    </LinearLayout>

    <Button
        android:id="@+id/client_ok"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/ok" />
</LinearLayout>

效果图

 以上就是socket客户端和服务端全部代码,希望对你有帮助

举报

相关推荐

0 条评论