由于我的手机需要用笔记本开的wifi,躺在床上玩手机时需要关电脑或者是要让电脑放歌的时候总是不想下床,于是我想能不能用一个APP,然后通过局域网实现在手机上对电脑进行操控呢?说干就干。
我在电脑上用的是C++作为服务器, 然后在android手机上用socket连接电脑。在向电脑发送我要电脑执行的命令时,完全没有问题,可以正常发送,只要在电脑收到消息时处理一下乱码就可以了。同时,我想要在电脑处理了我发送的命令之后返回执行的结果,在这个地方出问题了。当我尝试在客户端启动接收消息的独立线程的时候,程序总是刚连接就挂了。然后把启动这个线程的代码注释掉重新编译就不会挂,但这样就没有办法接收返回的执行结果了,这是为什么呢?尝试了很多遍。
终于,今天我想到了一个可能的原因,android不能在主线程中访问网络,那么同理,是不是在子线程中也不能改变UI呢?(因为android的主线程就是UI线程)抱着试试看的心态,我试了一下在这个接收消息的线程中接收到消息之后不在UI上显示出来,只接收,但还是挂了。不对,但是我感觉这应该不是接收消息的问题了,在仔细看了一下代码之后,我发现,我的接收消息的线程启动的语句在连接服务器的语句后面,我连接服务器也是用了一个独立的线程来完成连接操作,瞬间我想到了为什么了。这个只是连接线程的入口,执行到这一句的下一句的时候并不意味着socket已经连接好了。因为并不是在同一个线程中,如果在这里启动接收消息的线程,当然会出问题,而且因为只是简单的做个测试,所以我的接收消息的时候并没有判断socket是不是连接的。
然后我的程序终于没有在第一次运行的时候就挂了。然而事情并没有想象的那么顺利,当我尝试在客户端循环接收服务器发来的消息的时候,问题又出现了。我用的是Bufferreader来读的。我尝试着把Bufferreader对象的定义放在readLine的前面,也就是说每一次readLine之前都要new 一次Bufferreader对象,重新绑定到socket上。线程的代码如下:
public class thread_reve extends Thread { public String str_reve = null; @Override public void run() { super.run(); while(true) { try { BufferedReader reader = new BufferedReader(new InputStreamReader(mainsocket.getInputStream())); str_reve = reader.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(!str_reve.equals("")) { message += " "; message += str_reve; } } } };
终于,在经历了重重磨难之后,我看到客户端可以终于可以很顺畅的接收客户端发来的每一条消息了。总结一下,如果我试了很多次不行的话就轻易放弃,当然得不到最后的成功。我会记住这次的教训。