0

The following code (mirror in this sample) seems work fine to receive little endian data (tested), but i'm needing to receive big endian (from a Android phone) and any attempt to revert the bytes result in inverted bytes with a strange character on end of data (see image below). And yes, i'm sending UTF8 bytes from android code.

IMAGE

I'm working in a async version of this code (see client part) that works very fine to receive bin data and text since the you revert the bytes order after first while iteration.

Here is the problematic code:

`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)
    {
        // Not Connected anymore ?
        return;
    }

    try
    {
        dataRead = c.socket.EndReceive(ar, out socketError);
    }
    catch (Exception)
    {
       // Your code goes here..
    }

    if (socketError != SocketError.Success)
    {
        // Has Connection been lost ?
        OnConnectionDropped(client);
        return;
    }

    if (dataRead <= 0)
    {
       // Has connection been lost ?
        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;

                // Handle the received messsage

               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);

                // Handle the received messsage

               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;
    }
}`
JOTA
  • 1
  • 2
  • You can use the right functions https://stackoverflow.com/a/51460573/5193536 – nbk Aug 16 '23 at 23:49
  • can you please elaborate, there are multiple answer try also some other solution from the answer – nbk Aug 17 '23 at 07:10
  • Probably you do message framing incorrectly, ie separating incoming strings. Btw, why use such legacy api? – Ryan Aug 17 '23 at 10:32

1 Answers1

0

OK, i not had get size of message correctly. Below is the solution:

if (!c.lengthRead)
{
    byte[] BodyLengthR = new byte[4];
    Array.Copy(c.Buffer, BodyLengthR, 4);
    Int32 Endian = BitConverter.ToInt32(BodyLengthR, 0);
    Int32 BodySize = IPAddress.NetworkToHostOrder(Endian);

    c.PrefixSize = BodySize + 4;
    Array.Resize(ref c.Buffer, c.PrefixSize);
    c.lengthRead = true;
}

//...

string text = Encoding.UTF8.GetString(c.Data.GetBuffer(), 4, (int)c.Data.Length); // 4 = ignore header
MessageBox.Show(text);
JOTA
  • 1
  • 2
  • Thank you for contributing to the Stack Overflow community. This may be a correct answer, but it’d be really useful to provide additional explanation of your code so developers can understand your reasoning. This is especially useful for new developers who aren’t as familiar with the syntax or struggling to understand the concepts. **Would you kindly [edit] your answer to include additional details for the benefit of the community?** – Jeremy Caney Aug 19 '23 at 01:03