最近在学习Android的socket通信,编写完服务器和客户端之后,发现只有客户端可以发送信息到服务器,但是服务器发送数据给客户端的时候,客户端并没有显示接收到数据,当服务器退出的时候,客户端才一股脑将服务器端发送的数据全都显示了出来,说起来惭愧,我看的疯狂Android,只选取了客户端部分编写,服务器端用的是之前自己写的Android4.0.3版本的简单服务器,疯狂Android书上写着:

   
while ((content = br.readLine()) != null) {    // 每当读取到来自服务器的数据之后,发送的消息通知程序    // 界面显示该数据    Message msg = new Message();    msg.what = 0x123;    msg.obj = content;    handler.sendMessage(msg);}
    当客户端读取的数据不为空,就会将数据以发送到handler处理,然后handler打印出数据,就这么简单的功能。

    查看了一些网友的情况,发现了这个问题(原来不止是我出现这个问题),原因也很简单,readline()方法是一个阻塞函数,阻塞函数就是当这个函数不执行完,函数所在线程就一直停止在这里不动,调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。(百度上面的)

    那readline()函数什么时候执行完呢?正常情况下,读取到"\r"、"\n"、"\r\n"就会返回,服务器退出或者异常,也会退出,这就是为什么我退出服务器之后,客户端会一股脑显示出所有数据的原因,因为那些数据都已经被存储到BufferedReader中了,服务器退出,客户端的readline()返回,程序往下走,将数据发送出去,触发handler里面的方法打印出了数据。

    有什么方法可以避免这种情况么?

    我回去找了一下疯狂Android的源代码,发现里面的服务器端发送数据的时候,居然是这样写的:

    os.write((content + "\n").getBytes("utf-8"));

    org………………

    就是说,服务器端为了给客户端知道我发送数据结束了,还需要在数据末添加一个"\n"。偷学了技能之后,我在服务器输入框中,输入一段信息,然后按下回车,再点击发送的时候,客户端成功接收并打印出了信息。

    我在查找readline()方法的时候,也看到一些网友们遇到了这个问题,而且他们写的真的是好,比我这种半吊子强多了,我个人参考了下面的文章:

http://blog.csdn.net/swingline/article/details/5357581

    谢谢大家,今晚就是这样。


彩蛋:

在搜索问题的时候,我发现一个很恐怖的事情,看下图:

Android socket通信 readline方法阻塞_第1张图片

org我错了,我真的错了,这个问题03年居然就有人讨论过了吗~~~

更多相关文章

  1. Android 客户端访问服务器以及服务器开发
  2. Android客户端与PC服务器实现Socket通信(wifi)
  3. Android adb forward转发TCP端口连接数据
  4. Android:SNS客户端开发四:数据库操作(二)
  5. Android之MVP模式实现登录和网络数据加载
  6. android 一个SQLite数据库多个数据表的基本使用框架 (带demo)
  7. 全程不用usb数据线,adb通过网络连接Android设备
  8. android(NDK+JNI)---Android使用JNI实现Java与C之间传递数据
  9. 【Android】利用Fiddler进行抓包详解教程。抓取接口以及数据,可以

随机推荐

  1. Craig Andrews » Best way to use HttpC
  2. ClickableSpan 的点击效果
  3. Color android
  4. Android中序列化对象到XMl 和 XML反序列
  5. android基础---对话框:Dialog、AlertDialo
  6. android.content.res.Resources$NotFound
  7. Android(安卓)studio debug代码时不显示
  8. 图文列表,关于Simpleadapter
  9. Android(安卓)touch screen Calibrate wi
  10. Android有时候EditText光标不显示,或者颜