首页 > 解决方案 > 通过 TCP 套接字发送消息 - Java(已关闭)

问题描述

我正在尝试通过 Android 中的 TCP 套接字发送消息,但它不起作用。(我的手机是客户端)

这是来自 TCPClient 类的代码:

public class TcpClient {
    public static String SERVER_IP = "192.168.200.1"; //server IP address
    public static final int SERVER_PORT = 1500;
    // message to send to the server
    private String mServerMessage;
    // sends message received notifications
    private OnMessageReceived mMessageListener = null;
    // while this is true, the server will continue running
    private boolean mRun = false;
    // used to send messages
    private PrintWriter mBufferOut;
    // used to read messages from the server
    private BufferedReader mBufferIn;
    private Socket socket;
    private Context context;
    /**
     * 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 String sendMessage(String message) {
        byte[] bytesToSend = message.getBytes();
        if (bytesToSend != null && socket != null && socket.isConnected()) {
            try {
                socket.getOutputStream().write(bytesToSend, 0, 9);
                return "deu";
            } catch (Exception e2) {
                e2.printStackTrace();
                return e2.getMessage();
            }
        }
        else return "aa";
    }

    /**
     * Close the connection and release the members
     */
    public void stopClient() {
        sendMessage("disconnecting");
        mRun = false;

        if (mBufferOut != null) {
            mBufferOut.flush();
            mBufferOut.close();
        }

        mMessageListener = null;
        mBufferIn = null;
        mBufferOut = null;
        mServerMessage = null;
    }

    public void run() {

        mRun = true;

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

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

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

            try {

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

                //receives the message which the server sends back
                mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // send login name
                sendMessage("connected");

                //in this while the client listens for the messages sent by the server
                while (mRun) {

                    mServerMessage = mBufferIn.readLine();

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

                }

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

            } 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 (UnknownHostException e) {
            e.getStackTrace();
        } catch (IOException e) {
            e.getStackTrace();
        }

    }

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

}

这是我的 MainActivity 的代码:

public class MainActivity extends AppCompatActivity {
    private Button btnInicio;
    private Button btnFinal;
    private Button btnRelatorio;
    private ImageView imgEcosonicsLogo;
    private TextView txtDataFinal;
    private TextView txtDataInicio;
    private Button btnConectar;
    private String recebido[];
    boolean connected = false;
    TcpClient mTcpClient;

    //COMUNICAÇÃO TCP
    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);
        }
    }

    private void init() {

        final AlertDialog.Builder avisoData = new AlertDialog.Builder(this);
        avisoData.setTitle("Atenção!");
        avisoData.setMessage("A data inicial não pode ser depois da final");
        avisoData.setPositiveButton("OK!", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });

        final AlertDialog.Builder avisoCon = new AlertDialog.Builder(this);
        avisoCon.setTitle("Atenção!");
        avisoCon.setMessage("Erro durante a conexão");

        final AlertDialog.Builder avisounkn = new AlertDialog.Builder(this);
        avisounkn.setTitle("Atenção!");
        avisounkn.setMessage("Erro unknow host");

        btnRelatorio = findViewById(R.id.btnRelatorio);
        btnRelatorio.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (inicio_ano > final_ano)
                    avisoData.show();
                else if ((inicio_mes + 1) > (final_mes + 1) && inicio_ano == final_ano)
                    avisoData.show();
                if (inicio_dia > final_dia) {
                    if ((inicio_mes + 1) == (final_mes + 1))
                        avisoData.show();
                }
                if (mTcpClient != null) {
                    avisoCon.setMessage(mTcpClient.sendMessage("relatorio"));
                    avisoCon.show();
                }
                else
                    avisoCon.show();
            }
        });

        btnConectar = findViewById(R.id.btnConectar);
        btnConectar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!connected) {
                    new ConnectTask().execute("");
                    btnConectar.setText("Desconectar");
                    connected = true;
                }
                else {
                    if (mTcpClient != null) {
                        mTcpClient.stopClient();
                        mTcpClient = null;
                    }
                    btnConectar.setText("Conectar");
                    connected = false;
                }
            }
        });
    }
    String string;

    int inicio_dia = 1;
    int inicio_mes = 0;
    int inicio_ano = 2019;
    int final_dia = 1;
    int final_mes = 0;
    int final_ano = 2019;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtDataFinal = findViewById(R.id.txtDataFinal);
        txtDataInicio = findViewById(R.id.txtDataInicio);
        btnInicio = findViewById(R.id.btnInicio);
        btnInicio.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Calendar rightNow = Calendar.getInstance();
                int year = rightNow.get(Calendar.YEAR);
                int month = rightNow.get(Calendar.MONTH);
                int dayOfMonth = rightNow.get(Calendar.DAY_OF_MONTH);
                DatePickerDialog datePickerDialog = new DatePickerDialog(MainActivity.this,
                        new DatePickerDialog.OnDateSetListener() {
                            public void onDateSet(DatePicker datePicker, int ano, int mes, int dia) {

                                inicio_dia = dia;
                                inicio_mes = mes;
                                inicio_ano = ano;

                                if (dia < 10) {
                                    if (mes < 10) {
                                        txtDataInicio.setText("0" + dia + "/" + "0" + (mes + 1) + "/" + ano);
                                    }
                                    else {
                                        txtDataInicio.setText("0" + dia + "/" + (mes + 1) + "/" + ano);
                                    }
                                }
                                else {
                                    if (mes < 10) {
                                        txtDataInicio.setText(dia + "/" + "0" + (mes + 1) + "/" + ano);
                                    }
                                    else {
                                        txtDataInicio.setText(dia + "/" + (mes + 1) + "/" + ano);
                                    }
                                }
                            }
                        },year, month, dayOfMonth);
                datePickerDialog.show();
            }
        });

        btnFinal = findViewById(R.id.btnFinal);
        btnFinal.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Calendar rightNow = Calendar.getInstance();
                int year = rightNow.get(Calendar.YEAR);
                int month = rightNow.get(Calendar.MONTH);
                int dayOfMonth = rightNow.get(Calendar.DAY_OF_MONTH);
                DatePickerDialog datePickerDialog = new DatePickerDialog(MainActivity.this,
                        new DatePickerDialog.OnDateSetListener() {
                            public void onDateSet(DatePicker datePicker, int ano, int mes, int dia) {

                                final_ano = ano;
                                final_dia = dia;
                                final_mes = mes;

                                if (dia < 10) {
                                    if (mes < 10) {
                                        txtDataFinal.setText("0" + dia + "/" + "0" + (mes + 1) + "/" + ano);
                                    }
                                    else {
                                        txtDataFinal.setText("0" + dia + "/" + (mes + 1) + "/" + ano);
                                    }
                                }
                                else {
                                    if (mes < 10) {
                                        txtDataFinal.setText(dia + "/" + "0" + (mes + 1) + "/" + ano);
                                    }
                                    else {
                                        txtDataFinal.setText(dia + "/" + (mes + 1) + "/" + ano);
                                    }
                                }
                            }
                        },year, month, dayOfMonth);
                datePickerDialog.show();
            }
        });

        imgEcosonicsLogo = findViewById(R.id.imgEcosonicsLogo);
        imgEcosonicsLogo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_VIEW);
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
                intent.setData(Uri.parse("http://www.ecosonics.com.br"));
                startActivity(intent);
            }
        });
        init();
    }
}

每次我按下 btnRelatorio 按钮时,它都会显示没有消息的 AlertDialog,并且不会向服务器发送任何数据。

这是调试控制台中显示的消息:

W/ViewRootImpl[MainActivity]: Dropping event due to root view being removed: MotionEvent { action=ACTION_MOVE, actionButton=0, id[0]=0, x[0]=516.49677, y[0]=-390.2551, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=132921874, downTime=132921863, deviceId=3, source=0x1002 }
W/InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed.
W/System.err: android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1598)
W/System.err:     at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:108)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
        at br.com.ecosonics.ecosmanager_wifi.TcpClient.sendMessage(TcpClient.java:52)
        at br.com.ecosonics.ecosmanager_wifi.MainActivity$2.onClick(MainActivity.java:116)
W/System.err:     at android.view.View.performClick(View.java:6312)
        at android.view.View$PerformClick.run(View.java:24802)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err:     at android.os.Looper.loop(Looper.java:169)
        at android.app.ActivityThread.main(ActivityThread.java:6521)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

PS:它发送消息“已连接”,警告客户端连接到服务器对不起我的英语不好,希望你能帮助我。

标签: javaandroidsocketstcp

解决方案


无需为您的英语感到抱歉!很好:)

android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1598)

当您的应用程序尝试在主线程上执行任何网络操作时,将引发上述错误。

您可以使用下面的代码来强制操作或创建一个单独的线程并执行操作。

选项1:强迫

    int SDK_INT = android.os.Build.VERSION.SDK_INT;
    if (SDK_INT > 8) 
    {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                .permitAll().build();
        StrictMode.setThreadPolicy(policy);
        //your codes here

    }

选项 2:单独的线程

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // do something in here
            }
        });
thread.start();

推荐阅读