WCF 流:最后一个字节丢失
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我没有确切的答案来解释为什么它有效(我的大脑目前还没有完全投入),但是它确实有效:(
并且,是的,你最终会得到一个太大的缓冲区。这只是一个开始进一步思考的点)
在测试中我发现+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:
(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.
为什么要传递(长度+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.