2012-06-10 63 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(); 
      } 
     } 
    } 

客戶

@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()表現得很奇怪。只有「連接」。在服務器上顯示。

有人能告訴我,我必須做些什麼才能正常發送消息?

編輯: 這是我發現的東西:

  • 如果我比所有發送更多的郵件,連接是空(NULL)之後,第二個連接錯誤顯示 - 請重新電話
  • 如果我在sendMessageToServer發送更多郵件沒有s.close行的連接只有一條消息正在通過。後面沒有顯示任何錯誤。總是(除非這個功能是沒有SystemClock.sleep(10))

  • 消息形式runTcpConnection節目希望這將幫助別人來診斷我的錯誤。

  • +0

    這是一大堆代碼和長時間的解釋。如果你的代碼的數量削減到一個小例子,人們可能會更容易幫助,特別是因爲這樣很應用題有哪些會獲得一些upvotes解決方案... –

    +0

    @KristopherMicinski我同意這是複雜的問題,但我無法再削減它。而關於他們全都只應用於一條消息的解決方案。 – sebap123

    回答

    2

    正如我所看到的,無論何時用戶點擊按鈕發送,你創建一個新的套接字,對吧?
    我建議你應該初始化它只有一次,當用戶點擊連接,然後使用它在發送click事件(因爲這是TCP,你會斷開與服務器,如果你創建套接字的新實例)
    所以,你應該刪除這些線sendMessageToServer

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

    和這條線在runTcpConnection

    s.close(); 
    

    當你不想與服務器通信時,套接字應該關閉(onstop是一個例子,或者當改變活動時...)
    你也應該只創建一個BufferedWriter實例。
    希望得到這個幫助。

    +0

    那麼,哪裏應該是s.close()? – sebap123

    +0

    @ sebap123:我已經更新了我的答案。 – R4j

    +0

    這是很好的答案。非常感謝你。你幫了我很多。 – sebap123

    相關問題