【问题标题】:Android: how to change IP Address from within TCP Client app?Android:如何从 TCP 客户端应用程序中更改 IP 地址?
【发布时间】:2017-01-11 19:32:26
【问题描述】:

我正在尝试在 C# TCP 服务器和 Android TCP 客户端之间进行通信。我是 android 新手,所以使用本教程的第二部分来创建 android 客户端: http://www.myandroidsolutions.com/2012/07/20/android-tcp-connection-tutorial/#.V8uZISgrKUk

一切正常,我可以在手机和计算机之间发送少量短信,但是本教程要求客户端应用程序将服务器 IP 硬编码到程序中,出于显而易见的原因,如果我实际上想制作一个使用它的应用程序。

在本教程之外,我添加了第二个 EditText ("@id/ipTxt") 和第二个按钮 ("@id/setIp")

由于我不想让任何人通读整个教程,因此总结了以下重要部分:

主要活动:

public class MyActivity extends Activity
{
    private ListView mList;
    private ArrayList<String> arrayList;
    private MyCustomAdapter mAdapter;
    private TCPClient mTcpClient;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        arrayList = new ArrayList<String>();

        final EditText editText = (EditText) findViewById(R.id.editText);
        Button send = (Button)findViewById(R.id.send_button);

        //relate the listView from java to the one created in xml
        mList = (ListView)findViewById(R.id.list);
        mAdapter = new MyCustomAdapter(this, arrayList);
        mList.setAdapter(mAdapter);

        // connect to the server
        new connectTask().execute("");

        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                String message = editText.getText().toString();

                //add the text in the arrayList
                arrayList.add("c: " + message);

                //sends the message to the server
                if (mTcpClient != null) {
                    mTcpClient.sendMessage(message);
                }

                //refresh the list
                mAdapter.notifyDataSetChanged();
                editText.setText("");
            }
        });

    }

    public class connectTask extends AsyncTask<String,String,TCPClient> {

        @Override
        protected TCPClient doInBackground(String... message) {

            //we create a TCPClient object and
            mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
                @Override
                //here the messageReceived method is implemented
                public void messageReceived(String message) {
                    //this method calls the onProgressUpdate
                    publishProgress(message);
                }
            });
            mTcpClient.run();

            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);

            //in the arrayList we add the messaged received from server
            arrayList.add(values[0]);
            // notify the adapter that the data set has changed. This means that new message received
            // from server was added to the list
            mAdapter.notifyDataSetChanged();
        }
    }
}

TCPClient 类:

public class TCPClient {

    private String serverMessage;
    public static final String SERVERIP = "192.168.0.102"; //your computer IP address
    public static final int SERVERPORT = 4444;
    private OnMessageReceived mMessageListener = null;
    private boolean mRun = false;

    PrintWriter out;
    BufferedReader in;

    /**
     *  Constructor of the class. OnMessagedReceived listens for the messages received from server
     */
    public TCPClient(OnMessageReceived listener) {
        mMessageListener = listener;
    }

    /**
     * Sends the message entered by client to the server
     * @param message text entered by client
     */
    public void sendMessage(String message){
        if (out != null && !out.checkError()) {
            out.println(message);
            out.flush();
        }
    }

    public void stopClient(){
        mRun = false;
    }

    public void run() {

        mRun = true;

        try {
            //here you must put your computer's IP address.
            InetAddress serverAddr = InetAddress.getByName(SERVERIP);

            Log.e("TCP Client", "C: Connecting...");

            //create a socket to make the connection with the server
            Socket socket = new Socket(serverAddr, SERVERPORT);

            try {

                //send the message to the server
                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

                Log.e("TCP Client", "C: Sent.");

                Log.e("TCP Client", "C: Done.");

                //receive the message which the server sends back
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                //in this while the client listens for the messages sent by the server
                while (mRun) {
                    serverMessage = in.readLine();

                    if (serverMessage != null && mMessageListener != null) {
                        //call the method messageReceived from MyActivity class
                        mMessageListener.messageReceived(serverMessage);
                    }
                    serverMessage = null;

                }

                Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");

            } catch (Exception e) {

                Log.e("TCP", "S: Error", e);

            } finally {
                //the socket must be closed. It is not possible to reconnect to this socket
                // after it is closed, which means a new socket instance has to be created.
                socket.close();
            }

        } catch (Exception e) {

            Log.e("TCP", "C: Error", e);

        }

    }

    //Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
    //class at on asynckTask doInBackground
    public interface OnMessageReceived {
        public void messageReceived(String message);
    }
}

我的理论是每次单击“setIp”按钮时停止connectTask进程并创建一个新的,但这似乎是一种非常低效的方法,而且我不知道该怎么做这样做:(

有什么想法吗?

【问题讨论】:

    标签: android sockets tcp android-asynctask ip


    【解决方案1】:

    SERVERIPSERVERPORT 常量改为非静态变量,然后使用TCPClient 构造函数的附加输入值或作为AsyncTask.execute() 的输入参数初始化它们(然后将作为doInBackground() 方法的输入参数)。

    在您首先确定这些值之前,请不要调用execute(),无论是从应用的存储配置中,还是从用户界面中的用户那里。

    当您开始一项新任务时,将对象保存到您的主代码中的一个变量中(您当前没有这样做)。要取消连接,您可以在该变量上调用AsyncTask.cancel() 方法。确保您的connectTask.doInBackground()TCPClient.run() 代码定期检查AsyncTask.isCancelled() 方法,以便它们在返回true 时尽快退出。 AsyncTask documentation 中提到了这种技术。

    connectTask 对象运行完毕后,您可以创建一个具有不同输入值的新对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 2015-02-16
      • 2016-02-25
      • 2011-12-11
      • 2021-09-21
      • 2014-10-16
      • 1970-01-01
      相关资源
      最近更新 更多