2013-02-04 81 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应该在主线程中实现!)。

相关问题