Вопрос по chat, android, sockets, java – Сокетная связь между двумя приложениями на Android

4

У меня огромная проблема с моим приложением для Android, и я хотел бы попросить вас о помощи.

В настоящее время я пишу приложение Android Clietn-Server с использованием сокетов. Я нашел много учебных материалов в Интернете, и из них я создал основы для своего проекта. Однако все учебные пособия предназначены только для одной отправки сообщения, и это все. Мне нужно отправить больше из них, поэтому я пытался изменить его.

Это фрагменты кода, отвечающие за сервер и клиент. Остальное не важно в это время.

Server:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        serverStatus = (TextView) findViewById(R.id.server_status);
        recivedMsg = (TextView)findViewById(R.id.rec_msg);

        SERVERIP = getLocalIpAddress();

        Thread fst = new Thread(new ServerThread());
        fst.start();
    }

    public class ServerThread implements Runnable {

        public void run() {
            try {
                if (SERVERIP != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            serverStatus.setText("Listening on IP: " + SERVERIP);
                        }
                    });
                    serverSocket = new ServerSocket(SERVERPORT);
                    while (true) {
                        // listen for incoming clients
                        Socket client = serverSocket.accept();
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                serverStatus.setText("Connected." + System.getProperty("line.separator"));
                            }
                        });

                        try {
                            line = null;
                            while (connected) {
                                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                                if((line = in.readLine())!=null)
                                {
                                    Log.d("ServerActivity", line);
                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            if(recivedMsg.equals("CLOSE"))
                                            {
                                                recivedMsg.append("CLOSE socket");
                                                connected = false;
                                            }
                                            else
                                            {
                                                recivedMsg.append("MSG: " + line + System.getProperty("line.separator"));
                                            }
                                            // do whatever you want to the front end
                                            // this is where you can be creative
                                        }
                                    });
                                }
                                else
                                {
                                    recivedMsg.append("empty" + System.getProperty("line.separator"));
                                }
                            }
                            break;
                        } catch (Exception e) {
                            handler.post(new Runnable() {
                                @Override
                                public void run() {
                                    serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
                                }
                            });
                            e.printStackTrace();
                        }
                    }
                } else {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            serverStatus.setText("Couldn't detect internet connection.");
                        }
                    });
                }
            } catch (Exception e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        serverStatus.setText("Error");
                    }
                });
                e.printStackTrace();
            }
        }
    }

Client

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

        serverIp = (EditText) findViewById(R.id.server_ip);
        connectPhones = (Button) findViewById(R.id.connect_phones);

        sendField = (EditText) findViewById(R.id.send_field);
        sendMsg = (Button) findViewById(R.id.msg_send);

        connectPhones.setOnClickListener(connectListener);
        sendMsg.setOnClickListener(sendMessage);
    }

    @Override
    protected void onStop() {
         super.onStop();
         try {
                 BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                 //send output msg
                 String outMsg = "CLOSE"; 
                 out.write(outMsg);
                 out.flush();
                 // make sure you close the socket upon exiting
                 s.close();
         } catch (IOException e) {
                 e.printStackTrace();
         }
    }

    private OnClickListener connectListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            serverIpAddress = serverIp.getText().toString();
            runTcpConnection();
            sendMessageToServer("Msg");
        }
    };

    private OnClickListener sendMessage = new OnClickListener() {

        @Override
        public void onClick(View v) {
            sendMessageToServer(sendField.getText().toString());
        }
    };

    private void runTcpConnection() {
        try {
            s = new Socket(serverIpAddress, SERVERPORT);
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            //send output msg
            String outMsg = "TCP connecting to " + SERVERPORT + System.getProperty("line.separator"); 
            out.write(outMsg);
            out.flush();
            Log.i("TcpClient", "sent: " + outMsg);
            SystemClock.sleep(10);
            s.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    };

    public void sendMessageToServer(String str) {
        try {
                    s = new Socket(serverIpAddress, SERVERPORT);
                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                    //send output msg
                    String outMsg = str + System.getProperty("line.separator"); 
                    out.write(outMsg);
                    out.flush();
                    Log.i("TcpClient", "sent: " + outMsg);
                    s.close();
                } catch (UnknownHostException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    Log.d("", "hello222");
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    Log.d("", "hello4333");
                }

            }

На данный момент устройства подключены правильно. Кроме того, они отправляют первые сообщения о подключении (те, вOnClickListener connectListener). The problem is that when I am trying to send another message using sendMessageToServer it is impossible. Those messages shows only after client activity is destroyed.

Очень интересно, что безSystemClock.sleep(10); слушательrunTcpConnection() вести себя странно. Только "Подключено". отображается на сервере.

Может кто-нибудь сказать мне, что я должен сделать, чтобы нормально отправлять сообщения?

EDIT: Это то, что я нашел:

If I am at the connection sending more messages than all are empty (null) and after the second one connection error shows - please reconnect phones If I am at the connection sending more messages without s.close line in sendMessageToServer only one message is passing through. No error is displayed after it. The message form runTcpConnection shows always (except when in this function is no SystemClock.sleep(10))

Надеюсь, это поможет кому-нибудь диагностировать мою ошибку.

@KristopherMicinski Я согласен с тем, что это сложный вопрос, но я больше не мог его урезать. И о решениях, которые они все применили только к одному сообщению. sebap123
Это много кода и длинное объяснение. Если вы сократите объем кода до небольшого примера, люди, вероятно, с большей вероятностью помогут, особенно потому, что у очень прикладных вопросов, подобных этому, есть решения, которые получают мало голосов ... Kristopher Micinski

Ваш Ответ

1   ответ
2

вы создаете новый сокет всякий раз, когда пользователь нажимает кнопку отправить, верно?
Я рекомендую вам инициировать его только один раз, когда пользователь щелкает на кнопке connect, затем вы используете его в событии send click (поскольку это TCP, вы отключитесь от сервера, если создадите новый экземпляр сокета)
Итак, вы должны удалитьthese lines вsendMessageToServer :

s = new Socket(serverIpAddress, SERVERPORT);
s.close();

и эта строка вrunTcpConnection

s.close();

Сокет должен закрываться всякий раз, когда вы не хотите общаться с сервером (например, onstop или когда изменяется активность ...)
Также вам следует создать только один экземпляр BufferedWriter.
Надеюсь, это поможет.

Итак, где должен быть s.close ()? sebap123
это отличный ответ. Большое спасибо. Вы мне очень помогли. sebap123
@ sebap123: я обновил свой ответ.

Похожие вопросы