2017-08-03 49 views
0

我想与嵌入式设备通信以获取一些读数到我的android手机。套接字不发送任何东西,除非在调试模式下运行

public void ClickedLearn(View v){ 
    create_connection(); 
    request_packet(); 
    Handler handler=new Handler(); 
    handler.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      recieve_packet(); 
      if(isLearned){ 
       Savebtn.setVisibility(View.VISIBLE); 
      } 
      try { 
       client.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 
    },5000); 
} 
private void recieve_packet() { 
    Thread t=new Thread(new Runnable() { 
     @Override 
     public void run() { 

      try { 
       InputStream instream; 
       instream = client.getInputStream(); 
       int a = instream.available(); 
       if (a > 0) { 
        InputStreamReader inputStreamReader = new InputStreamReader(instream); 
        BufferedReader reader = new BufferedReader(inputStreamReader); 
        final String Recievedstring = reader.readLine(); 
        if (Recievedstring != null) { 
         Recieved_packet = Recievedstring; 
         isLearned=true; 

        } 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 

      } 
     } 
    }); 
    t.start(); 
    while(t.isAlive()); 

} 
private void request_packet() { 
    OutputStream outstream; 

    try { 
     outstream = client.getOutputStream(); 
     PrintWriter out = new PrintWriter(outstream); 
     String outputPacket="T"; 
     textflag1=true; 
     out.print(outputPacket); 
     out.flush(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
private void create_connection() { 
    final String text = "192.168.43.161:80"; 
    final int port; 
    final String ipaddress; 
    if (text != null) { 
     String[] splitted = text.split(":"); 
     ipaddress = splitted[0]; 
     port = Integer.parseInt(splitted[1]); 
     Thread t = new Thread() { 
      public void run() { 
       try { 
        client = new Socket(ipaddress, port); 
        isConnected = true; 

       } catch (IOException e) { 
        e.printStackTrace(); 
        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          Toast.makeText(getApplicationContext(), "Could not connect!", Toast.LENGTH_SHORT).show(); 
          finish(); 
         } 
        }); 
       } 
      } 
     }; 
     t.start(); 
     while (t.isAlive()) ; 
    } 
} 

如果我在request_packet里放置了一个断点,那么在调试模式下一切正常。但它不会在正常模式下工作,因为outputstream上的字符串没有发送。但是代码没有抛出任何异常。我不明白是怎么回事 请帮我...

回答

-1

我得到了解决方案。我过早地调用了send_packet函数。我稍微改变了ClickedLearn方法,它对我很有帮助。

public void ClickedLearn(View v){ 
    create_connection(); 
    Handler communication=new Handler(); 
    communication.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      request_packet(); 
      Handler handler=new Handler(); 
      handler.postDelayed(new Runnable() { 
       @Override 
       public void run() { 
        recieve_packet(); 
        if(isLearned){ 
         Savebtn.setVisibility(View.VISIBLE); 
        } 
        try { 
         client.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 

       } 
      },500); 
     } 
    },1000); 
} 
+0

我在问题的代码片段中看不到'send_packet',它在服务器端吗? –

+0

解决方案是阻止读取,直到数据到达,而不是试图摆弄时间。你不知道数据到达需要多长时间。 – EJP

0

这是因为你误用了InputStream.available()。进入调试模式会改变计时。只要删除测试。

并摆脱while (t.isAlive());循环。如果你想同步执行,为什么使用线程?

+0

它没有为我工作。我想我在建立连接之前过早调用send_packet。但InputStream.available()有什么问题?我以前多次使用过它。 – user3116339

+0

它有什么问题是没有意义的。你想要输入:为什么不等它呢?否则,如果'available()'返回0,则不调用'read()',所以你永远不会收到数据包。只需在'read()'中阻塞,直到数据到达。如果你在建立连接之前调用它,你会得到一个异常,但是如果你在数据到达之前调用它,你将得不到任何东西,就像你一样。这就是为什么调用'available()'毫无意义的原因,以及为什么删除它将修复它。 – EJP

0

如果我没有弄错,instream.available()是非阻塞的,如果192.168.43.161:80的响应尚未到达,您将得到0。因此对应于if (a > 0) {的分支将不会执行。现在,当你进入调试模式时,你只需要x毫秒就可以到达数据包。

为了与服务器你可以(作为用户EJB建议)块同步,等到数据可用,从而摆脱int a = instream.available()if (a > 0) {,突出部分使用reader.readLine()它会阻塞,直到数据可从服务器:

InputStream instream; 
instream = client.getInputStream(); 
InputStreamReader inputStreamReader = new InputStreamReader(instream); 
BufferedReader reader = new BufferedReader(inputStreamReader); 
final String Recievedstring = reader.readLine(); 
if (Recievedstring != null) { 
    Recieved_packet = Recievedstring; 
    isLearned=true; 
} 

作为一个额外的功能,你可以设置socket timeout option这将影响readLine()阻塞时间。

+0

你说得对。但我在处理程序中给了足够的时间来获取字节。在create_connection()和request_packet()之间留出一点时间就解决了问题。不知道确切原因。 – user3116339

+0

'InputStreams'阻塞。由于什么而获得零点? – EJP

+0

@EJP,我的错误,我的意思是'inputstream.available()'而不是'client.getInputStream()',我更新了我的回复;现在,'available()'是非阻塞的,如果没有更多的数据可供读取,它可以返回'0' –

相关问题