You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Socket.BeginReceive回调中如何正确处理大端字节序数据?

问题描述

我有一段代码,接收小端字节序数据时运行正常(已测试),但需要接收安卓设备发送的大端字节序数据时,尝试反转字节后出现字节倒置且数据尾部带有乱码的情况。安卓端确实发送的是UTF8格式的字节数据。

我基于某异步客户端代码编写了当前版本,原版本在首次while循环后反转字节序,接收二进制数据和文本时表现良好,但当前修改后的版本出现上述问题。

存在问题的代码

class Client
{
    public Socket socket;
    public Guid ID;
    public string RemoteAddress;
    public byte[] Buffer = new byte[1024];
    public int DataSize = 0;
    public int PrefixSize = 0;
    public uint tickCount = 0;
    public bool DataSizeReceived = false;
    public bool lengthRead = false;
    public MemoryStream Data = new MemoryStream();

    public Client(Socket socket)
    {
        this.socket = socket;
        ID = Guid.NewGuid();
        RemoteAddress = socket.RemoteEndPoint.ToString();
    }
}

private bool _IsConnected(Socket socket)
{
    try
    {
        return !(socket.Poll(1000, SelectMode.SelectRead) && socket.Available == 0);
    }
    catch (SocketException)
    {
        return false;
    }
}

private void ReceiveCallback(IAsyncResult ar)
{
    int dataOffset = 0;
    int restOfData = 0;
    int dataRead = 0;
    Boolean StreamClosed = false;
    long cDataLength = 0;
    long LastiDataLength = 0;

    SocketError socketError = SocketError.TypeNotFound;

    Client c = (Client)ar.AsyncState;

    if (!c.socket.Connected)
    {
        // 已断开连接?
        return;
    }

    try
    {
        dataRead = c.socket.EndReceive(ar, out socketError);
    }
    catch (Exception)
    {
       // 自定义异常处理代码
    }

    if (socketError != SocketError.Success)
    {
        // 连接已丢失?
        OnConnectionDropped(client);
        return;
    }

    if (dataRead <= 0)
    {
       // 连接已丢失?
        OnConnectionDropped(client);
        return;
    }
    
    while (dataRead > 0)
    {
        if (!c.DataSizeReceived)
        {
            if (!c.lengthRead)
            {
                c.PrefixSize = dataRead;
                Array.Resize(ref c.Buffer, c.PrefixSize);
                Array.Reverse(c.Buffer);
                c.lengthRead = true;
            }

            if (c.Data.Length > 0)
            {
                restOfData = c.PrefixSize - (int)c.Data.Length;
                c.Data.Write(c.Buffer, dataOffset, restOfData);
                dataRead -= restOfData;
                dataOffset += restOfData;
            }
            else if (dataRead >= c.PrefixSize)
            {
                c.Data.Write(c.Buffer, dataOffset, c.PrefixSize);
                dataRead -= c.PrefixSize;
                dataOffset += c.PrefixSize;
                c.lengthRead = false;

                // 处理接收到的消息
               string text = Encoding.UTF8.GetString(c.Data.GetBuffer(), 0, (int)c.Data.Length);
               MessageBox.Show(text);
                
               // ============================
            }
            else
            {
                c.Data.Write(c.Buffer, dataOffset, dataRead);
                dataOffset += dataRead;
                dataRead = 0;
            }

            if (c.Data.Length == c.PrefixSize)
            {
                c.DataSize = BitConverter.ToInt32(c.Data.GetBuffer(), 0);
                c.DataSizeReceived = true;
                c.Data.Position = 0;
                c.Data.SetLength(0);
                c.lengthRead = false;
            }
            else
            {
                c.socket.BeginReceive(c.Buffer, 0, c.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), c);
                return;
            }
        }

        try
        {
            cDataLength = c.Data.Length;
            LastiDataLength = cDataLength;
        }
        catch (ObjectDisposedException)
        {
            StreamClosed = true;
        }
        if (!StreamClosed)
        {
            if ((cDataLength + dataRead) >= c.DataSize)
            {
                restOfData = c.DataSize - (int)c.Data.Length;

                c.Data.Write(c.Buffer, dataOffset, restOfData);

                // 处理接收到的消息
               string text = Encoding.UTF8.GetString(c.Data.GetBuffer(), 0, (int)c.Data.Length);
               MessageBox.Show(text);
                
               // ============================

                dataOffset += restOfData;
                dataRead -= restOfData;

                c.Data = new MemoryStream();
                c.Data.Position = 0;
                c.DataSizeReceived = false;
                c.DataSize = 0;

                if (dataRead == 0)
                {
                    if (_IsConnected(c.socket))
                    {
                        c.socket.BeginReceive(c.Buffer, 0, c.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), c);
                        return;
                    }
                }
                else
                    continue;
            }
            else
            {
                if (_IsConnected(c.socket))
                {
                    c.Data.Write(c.Buffer, dataOffset, dataRead);

                    c.socket.BeginReceive(c.Buffer, 0, c.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), c);

                    dataRead = 0;
                }
            }
        }
        else
        {
            if (LastiDataLength + dataRead == c.DataSize)
            {
                if (_IsConnected(c.socket))
                {
                    c.socket.BeginReceive(c.Buffer, 0, c.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), c);
                }
                return;
            }
            else
            {

            }
        }

        if (!_IsConnected(c.socket))
            dataRead = -1;
    }
}

内容的提问来源于stack exchange,提问作者JOTA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 03:16:16