C# TCP 客户端处理异步消息时出错
本文关键字:消息 出错 异步 处理 TCP 客户端 | 更新日期: 2023-09-27 18:33:26
>我在使用TCP客户端时遇到了一些问题,该服务连接到服务器并侦听消息,这些消息在90%的时间内被接收和处理。经过一些调试,我发现在某些情况下我收到"无法读取整个数据包!"错误。(在代码中)
我无法控制服务器发送的内容。我的想法是它没有收到完整的消息(我认为它在较长的消息上失败,但由于数量而不确定)。
我能解释这个问题的最好方法是什么?或任何其他提示。我在下面有我的接收方法,这是所有操作和问题所在。
很抱歉这是我第一次尝试使用TCP,所以不要害怕
public void Receive(IAsyncResult ar)
{
if (ar != null)
{
try
{
byte[] mLenBytes = (byte[])ar.AsyncState;
byte[] mDataBytes = null;
int bytes_read = mTcpClient.Client.EndReceive(ar);
if (bytes_read != 4)
throw new Exception("Unable to read whole header!");
int len = mLenBytes[3] + ((mLenBytes[2] + (mLenBytes[1] + (mLenBytes[0] << 8)) << 8) << 8);
mDataBytes = new byte[len];
bytes_read = mTcpClient.Client.Receive(mDataBytes, len, SocketFlags.None);
if (bytes_read != len)
throw new Exception("Unable to read whole packet of data!" + "Expected " + len + " Got " + Convert.ToString(bytes_read) + "'r'n" + (System.Text.Encoding.ASCII.GetString(mDataBytes)));
//This is the error that is raised!.
// raise an event
PhoneBoxEventArgs e1 = new PhoneBoxEventArgs(System.Text.Encoding.UTF8.GetString(mDataBytes));
Console.WriteLine("Data received is = " + e1.Data);
OnPassEvent(e1);
}
catch (Exception ex)
{
}
}
byte[] mLenBytes_new = new byte[4];
mTcpClient.Client.BeginReceive(mLenBytes_new, 0, 4, SocketFlags.None, new AsyncCallback(Receive), mLenBytes_new);
}
您不能假设从TCP服务器一次读取整个"消息"。这通常是你做整个标题的东西的原因。
标头应该有 4 个字节长,并告诉您后面要跟多少字节。所以你需要做的是:
- 异步读取,直到有 4 个字节
- 继续异步读取,直到您知道在标头中接收的字节数与被告知的字节数一样多
您正在做的是:
- 假设您一次获得 4 个字节
- ,如果不这样做就会失败(问题:您不能假设您在一次接收中获得 4 个字节) 接收尽可能多的字节,
- 如果没有获得足够的字节,则失败(再次出现问题:您无法确保一次性接收所有字节)
此外,我可以从您的代码中看出您已经开始异步接收。为什么在获得标头后切换到同步接收?