网络流中的额外字节

时间:2011-02-15 11:03:19

标签: .net vb.net

我有一个带有2个进程的.net应用程序,使用网络流进行通信。 该协议由一组命令组成,一些命令带有参数,这些命令通过流发送到服务器。服务器处理命令,并发送响应。

其中一个命令的协议如下所示:

Dim bytes() As Byte
stream.WriteByte(CmdId)
bytes = BitConverter.GetBytes(bufferSize)
stream.Write(bytes, 0, bytes.Length)
stream.Write(buffer, offset, bufferSize)
bytes = BitConverter.GetBytes(singleValue1)
stream.Write(bytes, 0, bytes.Length)
bytes = BitConverter.GetBytes(singleValue2)
stream.Write(bytes, 0, bytes.Length)
bytes = BitConverter.GetBytes(intValue1)
stream.Write(bytes, 0, bytes.Length)
bytes = BitConverter.GetBytes(intValue2)
stream.Write(bytes, 0, bytes.Length)

所以基本上我发送了一大块字节(长度不一,但是数以千计),其次是2个单词,2个整数)。 在接收端,我有:

Dim bytes(3) As Byte
cmd = stream.readByte()
stream.Read(bytes, 0, 4)
Dim bufferSize As Integer = BitConverter.ToInt32(bytes, 0)
Dim buf(bufferSize - 1) As Byte
Dim nRead As Integer = 0
While nRead < bufferSize
  nRead += stream.Read(buf, nRead, bufferSize - nRead)
End While
stream.Read(bytes, 0, 4)
Dim s1 As Single = BitConverter.ToSingle(bytes, 0)
stream.Read(bytes, 0, 4)
Dim s2 As Single = BitConverter.ToSingle(bytes, 0)
stream.Read(bytes, 0, 4)
Dim i1 As Integer = BitConverter.ToInt32(bytes, 0)
stream.Read(bytes, 0, 4)
Dim i2 As Integer = BitConverter.ToInt32(bytes, 0)

通常,这很好用。很少(可能每几百万次调用一次),阅读方得到错误的值。我添加了代码来跟踪发送和接收的值。这表明有时候,读取端会获得两个额外的字节,值为0,这是写入端未发送的。这些额外的字节出现在不同的地方,例如在一个案例中,他们介于i1和i2之间;在另一个中,它们位于s2的第一个和第二个字节之间。

有谁知道这两个字节可能来自哪里?我检查了我的代码,并且跟踪了写入流的每个地方,因此看起来它们实际上并没有写入流。值得注意的是,在当前的实现中,s1始终为0。

1 个答案:

答案 0 :(得分:2)

每次执行stream.Read(bytes, 0, 4)时,都无法检查结果代码。总是有足够的数据来填充4个字节是很少见的。将其重构为“read me 4 bytes”方法,正确执行,检查(循环)已读取的4个字节。

实际上,我发现在填充缓冲区时,正确这一点很奇怪,但在读取int / single时却没有。例如,你可以(用C#术语)

static void Read(Stream stream, byte[] buffer, int offset, int count) {
    int read;
    while(count > 0 && (read = stream.Read(buffer, offset, count)) > 0) {
        count -= read;
        offset += read;
    }
    if(count > 0) throw new EndOfStreamException();
}

然后

Read(stream, bytes, 0, 4)
Dim s1 As Single = BitConverter.ToSingle(bytes, 0)