2013-02-04 165 views
0

我正在構建一個非常簡單的應用程序,它由一個客戶端組成,用戶在其中輸入一個發送到服務器的字符串。然後,一旦服務器收到該消息,它就會將其發送回客戶端。 我的問題是,當我嘗試讀取服務器發送的消息時,我在客戶端上發生錯誤。如何在客戶端發送和接收消息?

一旦插座被打開,下面的代碼片段顯示了客戶端如何嘗試發送和接收消息:

PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket 
         .getOutputStream())),true); 
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

out.println(message); 

if (in.readLine()!=null) 


    response=in.readLine(); 

我越來越閱讀‘在’的當strictMode $ AndroidBlockGuardPolicy.onNetwork()異常變量(in.readLine())

服務器端如下:

while ((line = in.readLine()) != null) { 
          final String line2=line; 
          handler.post(new Runnable() { 
           @Override 
           public void run() { 
            serverStatus.setText(line2); 
           } 
          }); 
          out.println("Message received:"+line2); 

我唯一希望的是將消息發送給客戶端確認服務器上的消息已收到。我面臨的另一個問題是需要時間讓服務器接收消息,讀取消息並將消息發回給客戶端,因此客戶端應該等待一秒鐘。我可以爲此使用什麼? 睡眠方法是否合適?

Thread.sleep(1000); 

systemClock.sleep(1000); 

預先感謝

[UPDATE]

這是爲客戶端的代碼:

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

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

    messageServer = (EditText) findViewById(R.id.message); 
    communicatePhones = (Button) findViewById(R.id.send_message); 
    messageServer.setVisibility(View.GONE); 
    communicatePhones.setVisibility(View.GONE); 


} 

private OnClickListener connectListener = new OnClickListener() { 

    @Override 
    public void onClick(View v) { 
     if (!connected) { 
      serverIpAddress = serverIp.getText().toString(); 
      if (!serverIpAddress.equals("")) { 
       Thread cThread = new Thread(new ClientThread()); 
       cThread.start(); 
      } 
     } 
    } 
}; 

public class ClientThread implements Runnable { 

    public void run() { 
     try { 
      Log.d("ClientActivity", serverIpAddress); 
      InetAddress serverAddr = InetAddress.getByName(serverIpAddress); 
      Log.d("ClientActivity", "C: Connecting..."); 
      socket = new Socket(serverAddr, ServerActivity.SERVERPORT); 

      handler.post(new Runnable() { 
        @Override 
        public void run() { 
         serverIp.setVisibility(View.GONE); 
         connectPhones.setVisibility(View.GONE); 
         messageServer.setVisibility(View.VISIBLE); 
         communicatePhones.setVisibility(View.VISIBLE); 

         communicatePhones.setOnClickListener(communicateListener); 

         mensajeRecibido = (TextView) findViewById(R.id.mensaje_recibido); 
         mensajeRecibido.append(response); 
        } 
      }); 
      //socket.close(); 
      Log.d("ClientActivity", "C: Closed."); 
     } catch (Exception e) { 
      Log.e("ClientActivity", "C: Error", e); 
      connected = false; 
     } 
    } 

    private OnClickListener communicateListener = new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      message = messageServer.getText().toString(); 
      if (!serverIpAddress.equals("")) { 
       try { 
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket 
          .getOutputStream())), true);   

        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
        out.println(message); 
        Log.d("ClientActivity", "C: Sent."); 
        //Thread.sleep(6000); 
        SystemClock.sleep(2000); 
        /* handler.postDelayed(new Runnable() { 
         public void run() { 
           my_button.setBackgroundResource(R.drawable.defaultcard); 
         } 
        }, 2000); */ 
        if (in.readLine()!=null) 
         response=in.readLine(); 

       } catch (IOException e) { 
        Log.e("ClientActivity", "S: Error", e); 
       }    
      } 
     } 
    }; 
} 

}

我應該在哪裏創建communicateListener的OnClickListener對象?我試圖把它放在run方法裏面,並且我得到了一些錯誤,比如未知的communicatorsListener變量或無效的private修飾符。

+0

你應該在新的機器人異步做到這一點。例如:使用'new Thread()。start();'並將所有內容放入Thread的運行函數中。 –

+0

我在代碼中省略了那部分內容,但我展示的代碼片段位於Thread的運行函數內部。 – cracq

+0

那麼請重新檢查,因爲我非常確定您正在UI線程上執行一個網絡調用並獲取此'AndroidBlockGuardPolicy'錯誤。你可以顯示整個代碼或只是複查 –

回答

1

你知道,你是不是想通過不屬於主線程的線程訪問GUI元素?

它的不良做法,通過主線程訪問網絡... communicateListener看起來對我來說都是錯誤的...它是在GUI線程還是在ClientThread中運行?它假設在GUI線程中作爲其onClick事件運行 - 但內部邏輯看起來像網絡線程。您可以使用處理程序來執行此操作,或者只是調用網絡線程的方法,該方法可以是主線程的數據成員,但可以是主線程的數據成員onClick應該在主線程中實現!)。

相關問題