UWP StreamSocket中的错误,ReadAsync挂起

时间:2017-01-13 10:28:18

标签: c# sockets uwp

我相信我在StreamSocket实现中发现了一个严重错误。我搜索了这个,如果这是一个已知的问题,我就找不到任何信息。

问题是如果读取缓冲区很小并且内部的读取操作读取的字节数多于填充在提供的缓冲区中的字节数,则下一个读取操作将挂起而不是从内部缓冲区返回数据,以防缓冲区为第二个操作大于StreamSocket内部缓冲区中剩余块的大小。

UWP版本:

StreamSocket sock = new StreamSocket();
byte[] b1 = new byte[4]; // Small buffer for 1st read.
byte[] b2 = new byte[1024]; // Large buffer for 2nd read.
await sock.ConnectAsync(new HostName("smtp.gmail.com"), "25");
Stream inputStream = sock.InputStream.AsStreamForRead();
int n1 = await inputStream.ReadAsync(b1, 0, b1.Length);
int n2 = await inputStream.ReadAsync(b2, 0, b2.Length); // Hangs here.
sock.Dispose();

.NET核心版:

Socket sock = new Socket(SocketType.Stream, ProtocolType.Tcp);
await sock.ConnectAsync("smtp.gmail.com", 25);
NetworkStream inputStream = new NetworkStream(sock);
byte[] b1 = new byte[4]; // Small buffer for 1st read.
byte[] b2 = new byte[1024]; // Large buffer for 2nd read.
int n1 = await inputStream.ReadAsync(b1, 0, b1.Length);
int n2 = await inputStream.ReadAsync(b2, 0, b2.Length); // Works like a charm.
inputStream.Dispose();
sock.Dispose();

此外,StreamSocket不提供(或我无法找到)任何方法来确定其内部缓冲区中剩余的字节数。我在调试器中看到了这个值,但它不公开。如果此信息可用,我至少能够请求内部缓冲区中仍然可用的确切字节数(在本例中为ReadAsync工作),从而解决了这个问题。当然,我可以利用Reflection,但我不想依赖于查看StreamSocket和Stream类的私有变量。

使用通用Windows SDK版本10.0.14393.0进行测试

是预期的行为还是确实存在错误?

编辑:

嗯,我能够使用IInputStream使其与UWP一起工作:

StreamSocket sock = new StreamSocket();
await sock.ConnectAsync(new HostName("smtp.gmail.com"), "25");
Stream inputStream = sock.InputStream.AsStreamForRead();
Windows.Storage.Streams.Buffer buf1 = new Windows.Storage.Streams.Buffer(4);
IBuffer outBuf1 = await sock.InputStream.ReadAsync(buf1, 4, InputStreamOptions.Partial);
Windows.Storage.Streams.Buffer buf2 = new Windows.Storage.Streams.Buffer(1024);
IBuffer outBuf2 = await sock.InputStream.ReadAsync(buf2, 1024, InputStreamOptions.Partial);
sock.Dispose();

但是,我不能在生产代码中使用它(由于其他原因)必须使用Stream,而不是IInputStream。而且我相信,如果暴露了这个功能,它必须正确地与Stream一起工作(并且它是)。

0 个答案:

没有答案