如何使用NetworkStream.BeginRead读取所有请求的数据
本文关键字:请求 数据 读取 何使用 NetworkStream BeginRead | 更新日期: 2023-09-27 18:13:13
有一个异步服务器的代码。客户端发送报头-数据块大小+数据块。
服务器先异步读取报头,然后读取数据块。
我需要,在我读取数据块后运行BeginRead头读取部分,使线程异步。
问题:
当我得到DataCallBack时,在line中:
int bytesRead = ns.EndRead(result);
我没有得到我要求在
中读取的所有缓冲区mc.Client.GetStream () .BeginRead (mc。数据缓冲区,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();
错误代码-使异步读取- SYNC
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也没有关于应用程序的"完整消息"的概念。这取决于你,程序员,开发一个协议,让你的应用程序知道什么时候所有的数据已经发送。
如果您期望得到一定数量的字节,那么保持EndRead()返回值的总和,并在达到这个神奇的数字时停止。