- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我试图理解 NetworkStream.EndRead() 的 MSDN 示例。有些部分我不明白。
下面是示例(从 MSDN 复制):
// Example of EndRead, DataAvailable and BeginRead.
public static void myReadCallBack(IAsyncResult ar ){
NetworkStream myNetworkStream = (NetworkStream)ar.AsyncState;
byte[] myReadBuffer = new byte[1024];
String myCompleteMessage = "";
int numberOfBytesRead;
numberOfBytesRead = myNetworkStream.EndRead(ar);
myCompleteMessage =
String.Concat(myCompleteMessage, Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
// message received may be larger than buffer size so loop through until you have it all.
while(myNetworkStream.DataAvailable){
myNetworkStream.BeginRead(myReadBuffer, 0, myReadBuffer.Length,
new AsyncCallback(NetworkStream_ASync_Send_Receive.myReadCallBack),
myNetworkStream);
}
// Print out the received message to the console.
Console.WriteLine("You received the following message : " +
myCompleteMessage);
}
它使用 BeginRead() 和 EndRead() 从网络流中异步读取。整个事情是通过调用
myNetworkStream.BeginRead(someBuffer, 0, someBuffer.Length, new AsyncCallback(NetworkStream_ASync_Send_Receive.myReadCallBack), myNetworkStream);
其他地方(示例中未显示)。
我认为它应该做的是在单个 WriteLine(示例末尾的那个)中打印从 NetworkStream 接收到的整个消息。请注意,该字符串名为 myCompleteMessage
。
现在,当我查看实现时,我的理解出现了一些问题。
首先:该示例分配了一个新的方法本地缓冲区myReadBuffer
。然后调用 EndStream() 将收到的消息写入提供 BeginRead() 的缓冲区。这不是刚刚分配的 myReadBuffer
。网络流应该如何知道它?因此在下一行 numberOfBytesRead
中,来自空缓冲区的字节被附加到 myCompleteMessage
。其当前值为 ""
。在最后一行中,这条由许多 '\0'
组成的消息使用 Console.WriteLine
打印。
这对我来说没有任何意义。
我不明白的第二件事是 while
循环。
BeginRead
是一个异步调用。所以没有数据被立即读取。因此,据我了解,while 循环应该运行相当长的一段时间,直到实际执行某些异步调用并从流中读取数据,以便不再有可用数据。文档没有说 BeginRead
会立即将可用数据的某些部分标记为已读,所以我不希望它这样做。
这个例子并没有提高我对这些方法的理解。这个例子是错误的还是我的理解错误(我希望是后者)?这个例子是如何工作的?
最佳答案
我认为 BeginRead 周围的 while 循环 不应该存在。在 EndRead 完成之前,您不希望执行 BeginRead 多次。此外,还需要在 BeginRead 之外指定缓冲区,因为每个数据包/缓冲区可能使用多个读取。
有些事情你需要考虑,比如我的消息/ block 有多长(固定大小)。我应该在它前面加上一个长度吗? (可变大小) <datalength><data><datalength><data>
不要忘记它是一个 Streaming 连接,因此可以一次读取多个/部分消息/数据包。
伪例子:
int bytesNeeded;
int bytesRead;
public void Start()
{
bytesNeeded = 40; // u need to know how much bytes you're needing
bytesRead = 0;
BeginReading();
}
public void BeginReading()
{
myNetworkStream.BeginRead(
someBuffer, bytesRead, bytesNeeded - bytesRead,
new AsyncCallback(EndReading),
myNetworkStream);
}
public void EndReading(IAsyncResult ar)
{
numberOfBytesRead = myNetworkStream.EndRead(ar);
if(numberOfBytesRead == 0)
{
// disconnected
return;
}
bytesRead += numberOfBytesRead;
if(bytesRead == bytesNeeded)
{
// Handle buffer
Start();
}
else
BeginReading();
}
关于c# - 了解来自 MSDN 的 NetworkStream.EndRead() 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19113002/
与使用(双向)NetworkStream 的异步 IO 相关,MSDN说“每次调用 BeginRead 都必须调用一次 EndRead。” 即使对于 EndRead() 将抛出异常的情况,例如在发出
我对使用异步模式进行流读写比较陌生,想知道这个问题的答案是否如此明显,以至于没有明确地写在任何地方: 当调用 NetworkStream.BeginRead 时,我传递了一个回调参数,根据 MSDN,
我想知道在我的 C# 异步套接字中,在 EndRead 调用中接收到 0 字节是否意味着服务器实际上已经断开了我们的连接? 我看到的许多例子都表明是这种情况,但我收到的断开连接频率比我预期的要高得多。
我编写了一个通过 SslStream 进行通信的 TcpClient 和服务器。通信有效,但是当我从客户端向服务器发送消息时,服务器首先读取 1 个字节,然后在下一步中读取其余部分。例子:我想通过Cl
我还不太“了解”async 和 await,我正在寻找关于我将要解决的特定问题的一些说明。基本上,我需要编写一些代码来处理 TCP 连接。它基本上只是接收数据并处理它,直到连接关闭。 我通常使用 Ne
我正在使用 NetworkStream.BeginRead/EndRead 从套接字进行异步读取。 但是,NetworkStream.EndRead() 有时会返回 0(即从套接字读取了 0 个字节)
我试图理解 NetworkStream.EndRead() 的 MSDN 示例。有些部分我不明白。 下面是示例(从 MSDN 复制): // Example of EndRead, DataAvail
我编写了以下函数来使用 NetworkStream 的异步读取函数(BeginRead 和 EndRead)实现超时功能。它工作正常,直到我注释掉行 Trace.WriteLine("bytesRea
我是一名优秀的程序员,十分优秀!