gpt4 book ai didi

c# - 如何使用 NetworkStream.BeginRead 读取所有请求的数据?

转载 作者:太空宇宙 更新时间:2023-11-03 21:46:52 24 4
gpt4 key购买 nike

有一个异步服务器的代码。 Client 发送 Header - Data Block + Data Block 的大小。

服务器首先异步读取Header,然后读取Data Block。

我需要在读取数据 block 后运行 BeginRead 以读取 header 部分,以使线程异步。

问题:

当我得到 DataCallBack 时,在一行中:

int bytesRead = ns.EndRead(result);

我没有得到我要求读入的所有缓冲区

mc.Client.GetStream().BeginRead(mc.DataBuffer, 0, size, new AsyncCallback(DataCallBack), mc);

如果客户端发送 1MB 的数据,我可以获得不同数量的“bytesRead”。

问题:

如何强制“BeginRead”从连接中读取所有数据。它应该会导致 Header - Data 的新循环。

MyClient - 简单地包装 TcpClient;

代码:

    public  void DoAcceptTcpClientCallback(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
client.NoDelay = false;
// client.ReceiveBufferSize = 1024*1024;
listener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpClientCallback), listener);
MyClient mc = new MyClient(client);
ContinueRead(0,mc);
}

public void ContinueRead(int size, MyClient mc)
{
if (size != 0)
{
mc.DataBuffer = new byte[size];
mc.Client.GetStream().BeginRead(mc.DataBuffer, 0, size, new AsyncCallback(DataCallBack), mc);
}
mc.Client.GetStream().BeginRead(mc.HeaderBuffer, 0, 4, new AsyncCallback(HeaderCallBack), mc);

}

private void HeaderCallBack(IAsyncResult result)
{
MyClient mc = (MyClient)result.AsyncState;
NetworkStream ns = mc.Stream;
int bytesRead = ns.EndRead(result);
if (bytesRead == 0)
throw new Exception();
mc.TotalLengs = BitConverter.ToInt32(mc.HeaderBuffer, 0);
ContinueRead(mc.TotalLengs, mc);

}
private void DataCallBack(IAsyncResult result)
{
MyClient mc = (MyClient)result.AsyncState;
NetworkStream ns = mc.Stream;
int bytesRead = ns.EndRead(result);
if (bytesRead == 0)
throw new Exception();

错误代码 - 导致异步阅读 - 同步

        while (bytesRead < mc.TotalLengs)
{
bytesRead += ns.Read(mc.DataBuffer, bytesRead, mc.TotalLengs - bytesRead);
}

结束错误代码

        ContinueRead(0, mc);
ProcessPacket(mc.DataBuffer, mc.IP);
}

最佳答案

“如果客户端发送 1MB 的数据,我可以获得不同数量的“bytesRead”。”

是的...这就是 TCP 的工作原理。你无法改变这一点。 TCP 保证数据包的顺序,而不是它们的分组方式。数据包沿途的硬件和流量状况决定了数据分组(或取消分组)的方式。

“如何强制“BeginRead”从连接读取所有数据。”

TCP 不知道发送了多少数据。就其而言,连接只是无穷无尽的字节流;因此它无法读取“所有数据”,因为数据没有尽头(从它的角度来看)。 TCP 也不知道什么是关于您的应用程序的“完整消息”。作为程序员,您有责任开发一个协议(protocol),让您的应用程序知道何时发送了所有数据。

如果您期望一定数量的字节,则保留 EndRead() 返回值的运行总和,并在达到该魔数(Magic Number)时停止。

关于c# - 如何使用 NetworkStream.BeginRead 读取所有请求的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16520182/

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