WCF 流:最后一个字节丢失

发布于 2024-10-13 01:58:39 字数 1958 浏览 3 评论 0原文

我有一个 WCF 服务,它有一种返回流的方法。

[ServiceContract]
public interface IService1
{
    [OperationContract]
    MyMessage Test();
}

现在,MyMessage 的定义如下:

[MessageContract]
public class MyMessage
{
    public MyMessage(string file)
    {
        this.Stream = File.OpenRead(file);
        this.Length = Stream.Length;
    }

    [MessageHeader]
    public long Length;

    [MessageBodyMember]
    public Stream Stream;
}

Peachy。

该服务使用 basicHttpBinding 提供流式响应。这是绑定配置:

  <basicHttpBinding>
    <binding name="BasicStreaming"
             maxReceivedMessageSize="67108864" maxBufferSize="65536" transferMode="StreamedResponse" />
  </basicHttpBinding>

现在事情开始变得有趣。调用此服务时,如果我以特定方式读取流,最后一个字节会丢失。这是说明两种不同方法的代码:

        Service1Client client = new Service1Client();

        //this way the last byte is lost
        Stream stream1;
        var length = client.Test(out stream1);
        var buffer1 = new byte[length];
        stream1.Read(buffer1, 0, (int)length);
        File.WriteAllBytes("test1.txt", buffer1);
        stream1.Close();

        //here i receive all bytes
        Stream stream2;
        length = client.Test(out stream2);
        var buffer2 = new byte[length];
        int c = 0, b;
        while ((b = stream2.ReadByte()) != -1)
        {
            buffer2[c++] = (byte)b;
        }
        File.WriteAllBytes("test2.txt", buffer2);
        stream2.Close();

我确信我遗漏了一些东西,但是任何人都可以向我指出到底为什么会发生这种情况吗?最大的问题是,在另一个服务中,无论我以哪种方式读取流,我都会丢失最后一个字节,但也许通过识别这里的问题我也可以解决这个问题。

技术细节:

  • IIS 7.0
  • .NET 3.5
  • 基本 HTTP 绑定
  • 流式响应模式

注意: 我已经上传了隔离问题的项目,因此任何人都可以尝试一下:mediafire

I have a WCF service which has one method returning a stream.

[ServiceContract]
public interface IService1
{
    [OperationContract]
    MyMessage Test();
}

Now, MyMessage is defined like this:

[MessageContract]
public class MyMessage
{
    public MyMessage(string file)
    {
        this.Stream = File.OpenRead(file);
        this.Length = Stream.Length;
    }

    [MessageHeader]
    public long Length;

    [MessageBodyMember]
    public Stream Stream;
}

Peachy.

The service has a streamed response, using basicHttpBinding. This is the binding configuration:

  <basicHttpBinding>
    <binding name="BasicStreaming"
             maxReceivedMessageSize="67108864" maxBufferSize="65536" transferMode="StreamedResponse" />
  </basicHttpBinding>

Now this is where things start to get interesting. When calling this service, the last byte is lost if i read the stream in a particular way. Here is the code illustrating the two different approaches:

        Service1Client client = new Service1Client();

        //this way the last byte is lost
        Stream stream1;
        var length = client.Test(out stream1);
        var buffer1 = new byte[length];
        stream1.Read(buffer1, 0, (int)length);
        File.WriteAllBytes("test1.txt", buffer1);
        stream1.Close();

        //here i receive all bytes
        Stream stream2;
        length = client.Test(out stream2);
        var buffer2 = new byte[length];
        int c = 0, b;
        while ((b = stream2.ReadByte()) != -1)
        {
            buffer2[c++] = (byte)b;
        }
        File.WriteAllBytes("test2.txt", buffer2);
        stream2.Close();

I am sure I'm missing something, but can anyone point out to me exactly why this is happening? The biggest problem is that in another service, whichever way i read the stream, i lose the last byte, but maybe by identifying the problem here I can solve that one too.

Technical details:

  • IIS 7.0
  • .NET 3.5
  • Basic HTTP Binding
  • Streamed response mode

Note: I have uploaded the project isolating the problem, so anyone can try it out: mediafire

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

辞慾 2024-10-20 01:58:39

我没有确切的答案来解释为什么它有效(我的大脑目前还没有完全投入),但是它确实有效:(

var buffer1 = new byte[length+2];
stream1.Read(buffer1, 0, buffer1.Length);

并且,是的,你最终会得到一个太大的缓冲区。这只是一个开始进一步思考的点)

在测试中我发现+1不够大,但+2足够大。

I don't have an exact answer as to why this works (my brain isn't fully engaged at the moment), however this DOES work:

var buffer1 = new byte[length+2];
stream1.Read(buffer1, 0, buffer1.Length);

(and, yes, you end up with a buffer that's too large. It's just a starting point for further thinking)

In testing I found +1 isn't large enough, but +2 is.

救赎№ 2024-10-20 01:58:39

为什么要传递(长度+1)的计数?它应该是长度,否则您将尝试读取比可用字节多的字节。

Why passing a count of (length + 1)? It should be length, otherwise you are attempting to read one more byte than what is available.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文