安卓tcp ip通讯

news2024/9/22 16:54:58

废话不多说直接上代码

//权限 引入
    <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客户端和服务端全部代码,希望对你有帮助

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1487724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NumpyPython 笔记1 3.4

array.ndim 几维 array.shape 几行&#xff0c;几列 array.size 存在多少个元素 np.array 转化为矩阵 dtype 确定类型&#xff0c;并且确定精度64&#xff1f;32&#xff1f;16&#xff1f;数字越小&#xff0c;越不精确 二维 np.zeros 生成零矩阵&#xff0c;并且规…

java常用应用程序编程接口(API)——Instant,DateTimeFormatter,Period,Duration概述

前言&#xff1a; 整理下学习心得。打好基础&#xff0c;daydayup&#xff01; Instant Instant是时间线上的某个时刻/时间戳&#xff0c;通过获取Instant的对象可以拿到此刻的时间&#xff0c;该时间由两部分组成&#xff1a;1&#xff0c;从1970年1月1日00:00:00开始走到此刻…

驱动开发面试复习

创建字符设备 1 创建设备号 alloc_chrdev_region 2.创建cdev cdev_init 3.添加一个 cdev,完成字符设备注册到内核 cdev_add 4.创建类 class_create 5.创建设备 device_create 1.内核空间与用户空间数据 copy_from_user 和copy_to_user 俩个函数来完成。 copy_from_user 函数…

招聘人才小程序源码系统:多城市招聘平台+招聘会+职场咨询 带完整的搭建教程以及安装代码包

移动互联网的飞速发展&#xff0c;线上招聘已成为企业和求职者之间的重要桥梁。为了满足多城市、多行业、多岗位的招聘需求&#xff0c;以及提供一站式的求职服务&#xff0c;小编给大家分享一款“招聘人才小程序源码系统”。该系统不仅整合了多城市的招聘平台资源&#xff0c;…

ssm226基于jsp的快递管理系统的开发

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一 、设计说明 1.1 研究…

动态库制作

win下扩展名为.dll(dynamic linking library) linux下前缀为dll 扩展名为.so(shared object) linux 下使用动态库步骤 1&#xff0c;制作动态库&#xff0c; libmath.so 2&#xff0c;在主程序中包含动态库&#xff08;就是添加头文件的方法&#xff09; 3&#xff0c;编译…

IO 与 NIO

优质博文&#xff1a;IT-BLOG-CN 一、阻塞IO / 非阻塞NIO 阻塞IO&#xff1a;当一条线程执行read()或者write()方法时&#xff0c;这条线程会一直阻塞直到读取到了一些数据或者要写出去的数据已经全部写出&#xff0c;在这期间这条线程不能做任何其他的事情。 非阻塞NIO&…

[Java 探索之路~大数据篇] 新时代大数据流处理入门指南

本文主要介绍大数据基础&#xff0c;以及 flink 流计算 文章目录 【基础知识】1. 批处理与流处理1.批处理2.流处理 2. 为什么需要一个优秀的流处理框架1. 股票交易的业务场景2.生产者——消费者模型3. 流处理框架要解决的诸多问题&#xff08;1&#xff09;可扩展性&#xff08…

JS 对象数组排序方法测试

输出 一.Array.prototype.sort() 1.默认排序 sort() sort() 方法就地对数组的元素进行排序&#xff0c;并返回对相同数组的引用。默认排序是将元素转换为字符串&#xff0c;然后按照它们的 UTF-16 码元值升序排序。 由于它取决于具体实现&#xff0c;因此无法保证排序的时…

将六西格玛设计融入汽车制造:实践之路

在快节奏的现代生活中&#xff0c;汽车早已不再仅仅是一种交通工具&#xff0c;而是成为了展现个性、追求品质生活的重要象征。为了满足消费者日益增长的品质需求&#xff0c;汽车制造商们纷纷将目光投向了六西格玛设计这一先进的质量管理方法。那么&#xff0c;如何将六西格玛…

现在如何才能开通微信公众号留言功能?

为什么公众号没有留言功能&#xff1f;2018年2月12日之后直到现在&#xff0c;新注册公众号的运营者会发现一个问题&#xff1a;无论是个人还是企业的公众号&#xff0c;在后台都找不到留言功能了。这对公众号来说绝对是一个极差的体验&#xff0c;少了一个这么重要的功能&…

AWS的S3存储桶设置生命周期规则

业务场景&#xff1a;周期性备份数据到s3存储桶&#xff0c;设置定期删除&#xff0c;只保留一定周期内的存储数据&#xff0c;节省存储空间减少花费 1. 点击存储桶选择管理--->创建生命周期规则 2. 设置名称等参数 点击创建即可

VUE实现Office文档在线编辑,支持doc/docx、xls/xlsx、ppt/pptx、pdf等

1.微软提供的在线Office预览&#xff08;只能预览&#xff0c;不能编辑&#xff09; https://view.officeapps.live.com/op/view.aspx?src服务器上文档地址&#xff08;http开头&#xff09; 2.国内在线Office方案&#xff1a; 腾讯文档、石墨文档、飞书 优势&#xff1a;跨…

光路科技:工业以太网交换机引领工业互联网新篇章

随着全球范围内工业4.0的浪潮不断涌动&#xff0c;工业互联网作为其核心驱动力&#xff0c;正引领着工业生产向智能化、网络化的崭新阶段迈进。在这一转型的浪潮中&#xff0c;光路科技凭借其卓越的工业互联设备与创新解决方案&#xff0c;正为工业互联网领域的发展注入新的活力…

Unity 常用的4种灯光、制作镜子、灯光的调用修改数值、

创建灯光时&#xff0c;一般用4种&#xff1a;定向光、点光源、聚光、区域光、 定向光&#xff1a;太阳 点光源&#xff1a;灯泡 聚光灯&#xff1a;手电筒 区域光&#xff1a;烘焙-贴图 灯光选择已烘焙 需要先选择被烘焙的物体&#xff0c;然后再选择Contribute GI 等待进…

网络工程师笔记7

路由器需要知道下一跳和出接口才能把数据转发出去 各个协议的优先级 直连&#xff1a;0 OSPF&#xff1a;10 ISIS&#xff1a;15 静态&#xff1a;60 RIP :100 静态路由 ip route-static <目的ip地址> 掩码 下一跳地址 例…

一文彻底搞懂Redis持久化

文章目录 1. Redis持久化方式2. RDB(快照)2.1 手动方式2.2 自动方式2.3 何时触发 RDB 持久化2.4 RDB 相关配置 3. AOF(追加日志文件)3.1 AOF 文件解读3.2 AOF 的写入与同步3.3 AOF 重写3.4 AOF 重写面临的问题3.5 AOF相关配置 4. 混合持久化 1. Redis持久化方式 Redis持久化是…

你知道什么是 BitMap 吗?

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

哪个超声波清洗机品牌值得入手?销量榜品牌值得选购!

在科技日益发展的今天&#xff0c;超声波清洗技术以其高效、便捷和深度清洁的特点&#xff0c;已经深入到生活的诸多领域&#xff0c;从精密仪器到珠宝首饰&#xff0c;从眼镜框到假牙&#xff0c;甚至是厨房用品的日常护理&#xff0c;都能见到超声波清洗机的身影。面对市场上…

第105讲:Mycat垂直分表实战:从规划到解决问题的完整指南

文章目录 1.垂直分表的背景2.垂直分表案例实战2.1.垂直分表规划2.2.配置Mycat实现垂直分表2.3.重启Mycat2.4.在Mycat命令行中导入数据结构2.5.查看由Mycat分表后每个分片上存储的表2.6.Mycat垂直分表后可能遇到的问题2.7.垂直分表完成 1.垂直分表的背景 我们的商城系统数据库&…