2012-06-10 4 views
4

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

В настоящее время я пишу приложение для Android Clietn-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). Проблема в том, что когда я пытаюсь отправить другое сообщение, используя sendMessageToServer, это невозможно. Эти сообщения отображаются только после уничтожения активности клиента.

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

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

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

  • Если я в связи представляемого больше сообщений, чем все пустые (NULL), а после второй ошибки одно соединение показывает - пожалуйста, подключите телефоны
  • Если я нахожусь в связи с отправкой большего количества сообщений без строки s.close в sendMessageToServer, то проходит только одно сообщение. После этого после этого не появляется ошибка. всегда (кроме случаев, когда в этой функции нет SystemClock.sleep (10))

  • Форма сообщения runTcpConnection показывает Надеюсь, что это поможет кому-то, чтобы диагностировать мою ошибку.

  • +0

    Это код и длинное объяснение. Если вы сократите количество кода до небольшого примера, люди, скорее всего, с большей вероятностью помогут, тем более, что у очень прикладных вопросов, подобных этому, есть решения, которые получают немного upvotes ... –

    +0

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

    ответ

    2

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

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

    и эта линия в runTcpConnection

    s.close(); 
    

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

    +0

    Итак, где должно быть s.close()? – sebap123

    +0

    @ sebap123: Я обновил свой ответ. – R4j

    +0

    это отличный ответ. Большое спасибо. Ты мне очень помог. – sebap123

    Смежные вопросы