gpt4 book ai didi

c# - 了解来自 MSDN 的 NetworkStream.EndRead() 示例

转载 作者:太空狗 更新时间:2023-10-29 17:52:00 31 4
gpt4 key购买 nike

我试图理解 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/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com