使用socket读取服务器发送的数据问题

    xiaoxiao2021-04-17  31

    刚刚项目使用到socket进行数据的传送,其中数据的读取问题着实 费了老大的劲,以此分享希望能让有缘人少走弯路。

    new Thread() { @Override public void run() { try { mSocket = new Socket(SERVICEADD, DST_PORT); //设置socket读取数据流的超时时间 mSocket.setSoTimeout(5000); mSocket.setTcpNoDelay(true); //设置客户端close()方法起作用时延时30s关闭socket mSocket.setSoLinger(true, 30); mSocket.setSendBufferSize(4096); //防止服务器端无效时,客户端长时间处于连接状态 mSocket.setKeepAlive(true); OutputStream ou = mSocket.getOutputStream(); //向服务器发送要查询的数据 ou.write(queryContent.getBytes()); ou.flush(); //读取发来服务器信息 BufferedReader br = new BufferedReader(new InputStreamReader(mSocket.getInputStream())); List<QueryDatas> queryDatases = QueryFomart.formatSocketString(br); EventBus.getDefault().post(queryDatases); br.close(); mSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }.start();

    对于使用readLine读取数据的一个问题就是,无法走到while后面去,究其原因:

    1.误以为readLine()是读取到没有数据时就返回null(因为其它read方法当读到没有数据时返回-1),而实际上readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null;因为readLine()阻塞后,System.out.println(message)这句根本就不会执行到,所以在接收端就不会有东西输出。要想执行到System.out.println(message),一个办法是发送完数据后就关掉流,这样readLine()结束阻塞状态,而能够得到正确的结果,但显然不能传一行就关一次数据流;另外一个办法是把System.out.println(message)放到while循环体内就可以。

    2.readLine()只有在数据流发生异常或者另一端被close()掉时,才会返回null值。

    3.如果不指定buffer大小,则readLine()使用的buffer有8192个字符。在达到buffer大小之前,只有遇到”/r”、”/n”、”/r/n”才会返回。

    小结,使用readLine()一定要注意:

    1、读入的数据要注意有/r或/n或/r/n 2、没有数据时会阻塞,在数据流异常或断开时才会返回null 3、使用socket之类的数据流时,要避免使用readLine(),以免为了等待一个换行/回车符而一直阻塞 4、或者是服务器端在发送完数据就进行关闭

    转载请注明原文地址: https://ju.6miu.com/read-673534.html

    最新回复(0)