java BufferedReader特定长度返回NUL字符

我有一个TCP套接字客户端从服务器接收消息(数据)。 消息的类型长度(2个字节)+数据(长度字节),由STX和ETX字符分隔。

我正在使用bufferedReader来检索两个第一个字节,解码长度,然后从相同的bufferedReader再次读取适当的长度并将结果放入char数组中。

大多数时候,我没有问题,但是有些(收到的数千条信息中有1条),当试图从阅读器读取(长度)字节时,我只得到它的一部分,我的数组的其余部分被填充“ NUL“人物。 我想这是因为缓冲区尚未填充。

char[] bufLen = new char[2]; _bufferedReader.read(bufLen); int len = decodeLength(bufLen); char[] _rawMsg = new char[len]; _bufferedReader.read(_rawMsg); return _rawMsg; 

我用几种迭代的方式解决了这个问题:

  • 首先,我测试了我的数组的最后一个字符:如果它不是ETX,我会逐个读取bufferedReader中的字符,直到我到达ETX,然后重新启动我的常规例程。 结果是我基本上会丢弃一条消息。

  • 然后,为了仍然检索该消息,我会在我的“截断”消息中找到NUL字符的第一个出现,一次读取并存储一个附加字符,直到我到达ETX,并将它们附加到我的“截断”消息,确认长度是可以的。

它也有效,但我真的在想我能做得更好,比如在阅读之前检查缓冲区中我需要的字符总数是否可用,但找不到合适的方法…

任何想法/指针?

谢谢 !

InputStream读取方法可能返回短读取; 您必须检查返回值以确定读取的字符数,并继续读取循环,直到获得所需的数字。 该方法可能会阻止,但只会阻止某些数据可用,而不一定是您请求的所有数据。

大多数人最终编写了一个“readFully”方法,比如DataInputStream,它读取预期的数据量,或者抛出IOException:

 static public int readFully(InputStream inp, byte[] arr, int ofs, int len) throws IOException { int rmn,cnt; for(rmn=len; rmn>0; ofs+=cnt, rmn-=cnt) { if((cnt=inp.read(arr,ofs,rmn))==-1) { throw new IOException("End of stream encountered before reading at least "+len+" bytes from input stream"); } } return len; } 

这是我用于测试的示例服务器。主rcv的结构如下

 while((chars_read = from_server.read(buffer)) != -1) { to_user.write(buffer,0,chars_read); to_user.flush(); } 

实际的整个服务器低于……

  public static void main(String[] args) throws IOException { try { if (args.length != 2) throw new IllegalArgumentException("Wrong number of Args"); String host = args[0]; int port = Integer.parseInt(args[1]); Socket s = new Socket(host,port); final Reader from_server = new InputStreamReader(s.getInputStream()); PrintWriter to_server = new PrintWriter(new OutputStreamWriter(s.getOutputStream())); BufferedReader from_user = new BufferedReader(new InputStreamReader(System.in)); final PrintWriter to_user = new PrintWriter(new OutputStreamWriter(System.out)); to_user.println("Connected to " + s.getInetAddress() + ":" + s.getPort()); Thread t = new Thread() { public void run() { char [] buffer = new char[1024]; int chars_read; try { while((chars_read = from_server.read(buffer)) != -1) { to_user.write(buffer,0,chars_read); to_user.flush(); } } catch(IOException e) { to_user.println(e); } to_user.println("Connection closed by server"); to_user.flush(); System.exit(0); } }; t.setPriority(Thread.currentThread().getPriority() + 1); t.start(); String line; while ((line = from_user.readLine()) != null) { to_server.println(line); to_server.flush(); } //t.stop(); s.close(); to_user.println("Connection closed by client"); to_user.flush(); } catch(Throwable e) { e.printStackTrace(); System.err.println("Usage : java TCPClient  "); } }