Java 字节流。读取操作有时不读取写入的内容
Java stream of byte. Read operation sometimes doesn't read what was written
我正在尝试实现一个具有自动重复请求策略的通信系统。我用了三个类:Transmitter,Channel,Receiver。我有消息的最大字节数 (window)。但是当我收到发送的字节时,有时我收到的字节数少于window。为什么?
我的代码是这样的:
传送器
int n = 0;
int remaining, length;
while (n<channelBytes.length) {
remaining = channelBytes.length-n;
length = (remaining<window)? remaining : window;
outputStream.write(channelBytes,n,length);
// wait for the ack
byte[] b = new byte[4];
channel.socket().setSoTimeout(2000);
inputStream.read(b);
n += ByteBuffer.wrap(b).getInt();
}
频道
bytes = new byte[SystemModel.WINDOW];
while(true) {
// receive from Tx
upInputStream.read(bytes);
// insert channel error
insertError(bytes);
Thread.sleep(propagationDelay + transmissionDelay);
// send bytes to Rx
downOutputStream.write(bytes);
// wait for the ack from Rx
clientChannelDown.socket().setSoTimeout(2000);
byte[] ack = new byte[4];
downInputStream.read(ack);
// send ack to Tx
upOutputStream.write(ByteBuffer.allocate(4).put(ack).array());
}
接收者
byte[] b = new byte[SystemModel.WINDOW];
while (true) {
try {
int received = inputStream.read(b);
channelCoding.decodePartially(b);
}catch (SocketTimeoutException te){
break;
} catch (IOException e) {
e.printStackTrace();
} catch (DataFormatException e) {
// send ack
int ack = Integer.parseInt(e.getMessage());
try {
outputStream.write(ByteBuffer.allocate(4).putInt(ack).array());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
在接收器中,字节数组 "b" 并不总是 window 的长度。
无效代码。请参阅 Java 文档。 InputStream.read(byte[] [,...])
没有义务传输超过一个字节,并且在不将结果存储到变量中的情况下调用它是永远无效的。如果您期望超过一个字节,则必须循环或使用 DataInputStream.readFully().
在Java中复制流的规范方式如下:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
对于ByteBuffers
和Channels
的情况如下:
while (in.read(buffer) > 0 || buffer.position() > 0)
{
buffer.flip();
out.write(buffer);
buffer.compact();
}
如果您编码正确,则无需将睡眠插入网络代码。
E&OE
我正在尝试实现一个具有自动重复请求策略的通信系统。我用了三个类:Transmitter,Channel,Receiver。我有消息的最大字节数 (window)。但是当我收到发送的字节时,有时我收到的字节数少于window。为什么? 我的代码是这样的:
传送器
int n = 0;
int remaining, length;
while (n<channelBytes.length) {
remaining = channelBytes.length-n;
length = (remaining<window)? remaining : window;
outputStream.write(channelBytes,n,length);
// wait for the ack
byte[] b = new byte[4];
channel.socket().setSoTimeout(2000);
inputStream.read(b);
n += ByteBuffer.wrap(b).getInt();
}
频道
bytes = new byte[SystemModel.WINDOW];
while(true) {
// receive from Tx
upInputStream.read(bytes);
// insert channel error
insertError(bytes);
Thread.sleep(propagationDelay + transmissionDelay);
// send bytes to Rx
downOutputStream.write(bytes);
// wait for the ack from Rx
clientChannelDown.socket().setSoTimeout(2000);
byte[] ack = new byte[4];
downInputStream.read(ack);
// send ack to Tx
upOutputStream.write(ByteBuffer.allocate(4).put(ack).array());
}
接收者
byte[] b = new byte[SystemModel.WINDOW];
while (true) {
try {
int received = inputStream.read(b);
channelCoding.decodePartially(b);
}catch (SocketTimeoutException te){
break;
} catch (IOException e) {
e.printStackTrace();
} catch (DataFormatException e) {
// send ack
int ack = Integer.parseInt(e.getMessage());
try {
outputStream.write(ByteBuffer.allocate(4).putInt(ack).array());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
在接收器中,字节数组 "b" 并不总是 window 的长度。
无效代码。请参阅 Java 文档。 InputStream.read(byte[] [,...])
没有义务传输超过一个字节,并且在不将结果存储到变量中的情况下调用它是永远无效的。如果您期望超过一个字节,则必须循环或使用 DataInputStream.readFully().
在Java中复制流的规范方式如下:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
对于ByteBuffers
和Channels
的情况如下:
while (in.read(buffer) > 0 || buffer.position() > 0)
{
buffer.flip();
out.write(buffer);
buffer.compact();
}
如果您编码正确,则无需将睡眠插入网络代码。
E&OE