Android中使用BufferedReader.readline阻塞读取不到数据,但是ready返回true
2017-06-02 16:08
375 查看
通过socket测试工具在电脑上发送消息,Android真机可以收到响应BufferedReader.ready()返回true,但是readline却一直阻塞。
原因:readline()只有在遇到换行符的时候才会结束,因为发消息的时候加一个换行符即可。
测试工具下载地址:http://files.cnblogs.com/files/feijian/SocketTool.rar
附上我的socket客户端代码:
原因:readline()只有在遇到换行符的时候才会结束,因为发消息的时候加一个换行符即可。
测试工具下载地址:http://files.cnblogs.com/files/feijian/SocketTool.rar
附上我的socket客户端代码:
public class QpushClient implements Runnable { protected static QpushClient mInstance; protected Handler mHandler; protected InetSocketAddress mAddress; protected String TAG = "QpushClient"; private final int TIME_OUT = 5 * 1000; //巡检周期 private final int CHECK_PERIOD = 2 * 1000; //连接尝试间隔时间 private final int CONNECT_PERIOD = 30 * 1000; private final int HEARTBEART_PERIOD = 10 * 1000; //若连接失败或响应失败,则尝试次数为9,若仍无效,则不再尝试 private final int CONNECT_TRY_TIMES = 9; //连接尝试次数 private int mConnectCount; Socket mClientSocket; String mHost; int mPort; //设置是否去读取数据 boolean isStartRecieveMsg = false; //开启心跳检测 boolean isKeepHeartBeat = false; private QpushClient(Handler handler) { mHandler = handler; } public static QpushClient getInstance(Handler handler) { if (mInstance == null) { mInstance = new QpushClient(handler); } return mInstance; } public void init(String host, int port) { mHost = host; mPort = port; new Thread(this).start(); isStartRecieveMsg = true; isKeepHeartBeat = true; } @Override public void run() { mAddress = new InetSocketAddress(mHost, mPort); if (mClientSocket == null) { mClientSocket = new Socket(); } //尝试连接,若未连接,则设置尝试次数 while (!mClientSocket.isConnected() && mConnectCount < CONNECT_TRY_TIMES) { connect(); if (!mClientSocket.isConnected()) { mConnectCount++; sleep(CONNECT_PERIOD); } else { mConnectCount = 0;//连接上,则恢复置0 } } if (mClientSocket.isConnected()) { //开始登陆 sendMsg("login"); recvMsg(); keepHeartBeat(); } } private void connect() { try { mClientSocket.connect(mAddress); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "mClientSocket.connect fail " + e.getMessage()); } } /** * 心跳维护 */ private void keepHeartBeat() { //设置心跳频率,启动心跳 while(isKeepHeartBeat){ sendMsg("我是心跳包"); sleep(HEARTBEART_PERIOD); } } BufferedWriter mWriter; BufferedReader mReader; /** * 不断的检测是否有服务器推送的数据过来 */ public void recvMsg() { while (mClientSocket != null && mClientSocket.isConnected() && !mClientSocket.isClosed()) { try { mReader = new BufferedReader(new InputStreamReader(mClientSocket.getInputStream(), "utf-8")); while (isStartRecieveMsg) { Log.e(TAG, "recvMsg5"); if (mReader.ready()) { Log.e(TAG, "recvMsg6"); /*读取一行字符串,读取的内容来自于客户机 reader.readLine()方法是一个阻塞方法, 从调用这个方法开始,该线程会一直处于阻塞状态, 直到接收到新的消息,代码才会往下走*/ String data = mReader.readLine(); Log.e(TAG,"isStartRecieveMsg data="+data); //handler发送消息,在handleMessage()方法中接收 handlerMsg(data); } Thread.sleep(200); } } catch (InterruptedException ex) { ex.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } sleep(200); } if (!mClientSocket.isConnected()) { connect(); recvMsg(); } sleep(CHECK_PERIOD); } private void sleep(long sleepTime) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 销毁socket */ public void onDestory() { if (mClientSocket != null) { try { mClientSocket.close(); } catch (IOException e) { e.printStackTrace(); } mClientSocket = null; } } public void sendMsg(String message) { PrintWriter writer; try { writer = new PrintWriter(new OutputStreamWriter( mClientSocket.getOutputStream()), true); writer.println(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * Ready for use. */ public void close() { try { if (mClientSocket != null && !mClientSocket.isClosed()) mClientSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 处理服务器返回过来的消息 * @param data */ private void handlerMsg(String data){ //对数据进行protobuf解析 //消息类型:1=登录成功、2=心跳检测、3=推送消息 int msgType=1; switch(msgType){ case 1: sendMsg("success"); break; case 2: sendMsg("success"); break; case 3: //需要通知service sendMsg("success"); mHandler.obtainMessage(QpushService.PUSH_TYPE_DATA, data).sendToTarget(); break; } } }
相关文章推荐
- 当获取相似数据时,使用不同方法调用不同sp,但是使用同一个方法去用IIDataReader或者SqlDataReader读取数据时需要判断column name是否存在。
- android BufferedReader readLine 阻塞
- [JAVA]Socket中BufferedReader.readLine()的阻塞特性导致的数据无法多次发送的问题
- java编程,字符流BufferedReader,读取一行数据。finally,readLine
- Android入门篇六:使用意图传递数据之返回结果
- 使用 SqlDataReader 读取数据示例
- 读取 XML 数据时,超出最大字符串内容长度配额 (8192)。通过更改在创建 XML 读取器时所使用的 XmlDictionaryReaderQuotas 对象的 MaxStringContentLength 属性,可增加此配额。
- Android 使用SharedPreferences进行数据存储和读取数据
- java编写socket使用bufferedReader.readLine()问题研究
- android 使用Intent传递数据之返回结果
- Jsp读取数据库返回json数据,Android客户端接收json
- Jsp读取数据库返回json数据,Android客户端接收json
- 数据库操作_连接SQL Server数据库示例;连接ACCESS数据库;连接到 Oracle 数据库示例;SqlCommand 执行SQL命令示例;SqlDataReader 读取数据示例;使用DataAdapter填充数据到DataSet;使用DataTable存储数据库表;将数据库数据填充到 XML 文件;10 使用带输入参数的存储过程;11 使用带输入、输出参数的存储过程示;12 获得数据库中表的数目和名称;13 保存图片到SQL Server数据库示例;14 获得插入记录标识号;Exce
- 认识BufferedReader的readLine、ready,以及InputStream的available
- android使用SharedPreferences读取xml数据
- Android学习备忘011——使用Intent传递数据之返回结果
- infragistics.Web.Mvc 使用(读取后台返回的数据)
- 使用SqlDataReader读取数据示例
- 关于java中BufferedReader的read()及readLine()方法的使用注意
- 使用Ext.Extend:使用Ext的JsonReader读取本地数据实现grid分页