InputStream in.read()的行为与预期不同

时间:2015-05-07 22:41:59

标签: java sockets networking inputstream

我正在尝试使用TCP将文本文件传输到另一台服务器,它的行为与预期的不同。发送数据的代码是:

        System.out.println("sending file name...");
        String outputFileNameWithDelimiter = outputFileName + "\r\n"; //These 4 lines send the fileName with the delimiter
        byte[] fileNameData = outputFileNameWithDelimiter.getBytes("US-ASCII");
        outToCompression.write(fileNameData, 0, fileNameData.length);
        outToCompression.flush();

        System.out.println("sending content...");
        System.out.println(new String(buffer, dataBegin, dataEnd-dataBegin));
        outToCompression.write(buffer, dataBegin, dataEnd-dataBegin); //send the content
        outToCompression.flush();

        System.out.println("sending magic String...");
        byte[] magicStringData = "--------MagicStringCSE283Miami".getBytes("US-ASCII"); //sends the magic string to tell Compression server the data being sent is done
        outToCompression.write(magicStringData, 0, magicStringData.length);
        outToCompression.flush();

因为这是TCP,你不能像UDP一样发送离散数据包,我希望所有数据都在输入流中,我可以使用分隔符来分隔文件名,内容和结束字符串然后每个in.read()只会给我下一个后续数据量。

相反,这是我在每次阅读时获得的数据:

On the first in.read() byteBuffer appears to only have "fileName\r\n". 
On the second in.read() byteBuffer still has the same information. 
On the third in.read() byteBuffer now holds the content I sent. 
On the fourth in.read() byteBuffer holds the content I sent minus a few letters.
On the fifth in.read() I get the magicString + part of  the message.

我正在刷新来自Web服务器的每一个发送,但输入流似乎没有实现可刷新。

任何人都可以解释为什么会这样吗?

编辑: 这就是我在阅读内容的方式。基本上这是在循环中然后写入文件。

 in.read(byteBuffer, 0, BUFSIZE);

2 个答案:

答案 0 :(得分:1)

如果您的期望是读取将填充缓冲区,或者准确接收对等方发送的单个write(),那么您的期望是错误的,而不是read().它不是& #39; t指定一次传输多个字节,并且不保证保留写边界。

如果不将read()的结果存储到变量中,则编写正确的代码是不可能的。

答案 1 :(得分:0)

当您从InputStream读取时,您要为其写入一个字节数组(以及可选的偏移量和最大读取量)。 InputStream不保证数组将填充新数据。返回值是实际读入它的字节数。

你的例子中发生了什么:

  • 第一个TCP数据包带有"fileName\r\n",写入缓冲区,到目前为止一切正常。
  • 您再次拨打read(),但下一个数据包尚未到达。 read()将返回0,因为在数据到达之前它不想阻止。所以缓冲区仍然包含"fileName\r\n" 。编辑:正如所指出的,read()总是阻塞,直到它读取至少一个字节。不知道为什么缓冲区没有改变。
  • 在第三次阅读时,内容已经到了。
  • 内容的第一部分被消息的第二部分覆盖,最后一部分仍然包含旧消息的一部分(我认为这就是你的意思)。
  • 等,你明白了

您需要检查返回值,等待数据到达,并且只使用上一个read()写入的缓冲区。