c# - 如何实现此阻塞 Socket 方法的异步、基于 TcpClient/NetworkStream 的端口?
问题描述
我有这样的代码:
public byte[] Read()
{
try
{
if (ClientSocket.Available != 0)
{
var InBuffer = new byte[ClientSocket.Available];
ClientSocket.Receive(InBuffer);
return InBuffer;
}
else
{
return null;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
我想在async
不完全改变代码流(疣和所有)的情况下做一个等价物,我遇到了问题,我也想切换到NetworkStream
它内置的async
方法
我希望 sig 是,Task<byte[]> Read()
但是:
NetworkStream.ReadAsync
期望通过 abyte[]
但不返回它,所以我不能简单地return stream.Read(...)
NetworkStream
似乎没有告诉您有多少字节可供读取。- 如果没有可用的数据,我不想调用
stream.Read
只是传回 null。
因此,无论上述方法中的问题如何——我知道这不是最优的——我该怎么做呢?
目标是我能做的,或同等的。
byte [] bytes = await x.Read();
解决方案
NetworkStream.ReadAsync 就像我遇到的大多数“给我一个字节缓冲区”方法一样;你给它一个字节数组并要求它从网络中读取 X 个字节并将其放入缓冲区。它可能比您要求的阅读量少,但不会阅读更多。它返回读取的字节数。您的代码始终保留字节数组缓冲区,因此您最终会执行以下操作:
byte[] buf = new byte[4096];
int bytesRead = await networkStream.ReadAsync(buf, 0, buf.Length. someCancelationToken);
byte[] rtn = new byte[bytesRead];
Array.Copy(buf, 0, rtn, 0, rtn.Length);
return rtn;
也就是说,您读取为异步操作,然后返回一个大小与报告为读取的字节数完全相同的数组,该数组来自缓冲区。使用此代码的方法将返回一个任务
NetworkStream 也有一个方法 CanRead 似乎可以解决您的“如果没有可阅读的内容”要求
还有一个 ReadAsync 的重载,它从您那里接受一个 Memory 作为缓冲区。你会以类似的方式使用它,除了当你知道已经读取了多少字节时你会调用它的 Slice 方法,以返回一个只查看缓冲区的那部分的内存。如果您随后在 Slice 调用的结果上调用 ToArray,您将获得一个大小符合您喜好的数组(读取字节数)。在这种情况下,两者可能几乎没有区别,尽管使用 Memory(及其相关的类 Span)可以减少某些操作的内存分配数量
推荐阅读
- linux - 需要 Jenkins 管道建议
- javascript - Uncaught (in promise) TypeError: Cannot read property 'filter' of undefined in Javascript
- parsing - ANTLR:如何优先考虑解析器规则替代
- zooming - 缩放(开放层)
- java - apache camel-kafka bridgeErrorHandler 不工作
- python - 如果我像人类一样行事(Selenium、Python),网站可以检测到网络抓取吗?
- javascript - 如何在 jQuery 的 $(document).ready() 方法中使用 div id 和 class?
- python-3.x - 如何从csv中删除多个符号
- c# - StackExchange.Redis - 无法解释的超时异常问题
- c++ - 如何在不运行脚本的情况下在 lua 脚本中打印错误?