我正在尝试使用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);
答案 0 :(得分:1)
如果您的期望是读取将填充缓冲区,或者准确接收对等方发送的单个write()
,那么您的期望是错误的,而不是read().
它不是& #39; t指定一次传输多个字节,并且不保证保留写边界。
如果不将read()
的结果存储到变量中,则编写正确的代码是不可能的。
答案 1 :(得分:0)
当您从InputStream
读取时,您要为其写入一个字节数组(以及可选的偏移量和最大读取量)。 InputStream
不保证数组将填充新数据。返回值是实际读入它的字节数。
你的例子中发生了什么:
"fileName\r\n"
,写入缓冲区,到目前为止一切正常。read()
,但下一个数据包尚未到达。 read()
将返回0
,因为在数据到达之前它不想阻止。所以缓冲区仍然包含"fileName\r\n"
read()
总是阻塞,直到它读取至少一个字节。不知道为什么缓冲区没有改变。您需要检查返回值,等待数据到达,并且只使用上一个read()
写入的缓冲区。