jsf*_*jsf 9 c# asynchronous networkstream tcpclient
我试图了解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);
}
Run Code Online (Sandbox Code Playgroud)
它使用BeginRead()和EndRead()从网络流异步读取.整个事情都是通过调用来调用的
myNetworkStream.BeginRead(someBuffer, 0, someBuffer.Length, new AsyncCallback(NetworkStream_ASync_Send_Receive.myReadCallBack), myNetworkStream);
Run Code Online (Sandbox Code Playgroud)
其他地方(未在示例中显示).
我认为它应该做的是在一个WriteLine(示例末尾的那个)中打印从NetworkStream接收的整个消息.请注意,该字符串被调用myCompleteMessage.
现在,当我查看实现时,我的理解会出现一些问题.
首先:该示例分配一个新的方法本地缓冲区myReadBuffer.然后调用EndStream(),将收到的消息写入提供BeginRead()的缓冲区.这不是myReadBuffer刚刚分配的.网络流应该如何知道它?所以在下一行 - numberOfBytesRead空缓冲区的字节被追加到myCompleteMessage.哪个有当前价值"".在最后一行中,'\0'打印了包含大量s的消息Console.WriteLine.
这对我没有任何意义.
我不明白的第二件事是while-loop.
BeginRead是异步调用.因此,不会立即读取任何数据.因此,据我所知,while循环应运行一段时间,直到实际执行某些异步调用并从流中读取,以便不再有可用的数据.该文档没有说BeginRead立即将可用数据的某些部分标记为正在读取,因此我不希望它这样做.
这个例子并没有提高我对这些方法的理解.这个例子是错的还是我的理解错了(我期待后者)?这个例子是如何工作的?
我认为BeginRead周围的while循环不应该存在.在EndRead完成之前,您不希望执行的BeginRead多于BeginRead.此外,需要在BeginRead之外指定缓冲区,因为每个数据包/缓冲区可能使用多个读取.
你需要考虑一些事情,比如我的消息/块(固定大小)有多长.我可以在前面添加一个长度.(可变大小) <datalength><data><datalength><data>
不要忘记它是一个流连接,因此可以在一次读取中读取多个/部分消息/数据包.
伪示例:
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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15179 次 |
| 最近记录: |