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
相关产品推荐
相关产品推荐

