首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# Socket 異步接收單片機數據:幀頭校驗與數據解析實戰

     編輯:程式設計綜合問答

在工業控制與物聯網項目中,單片機通過 WiFi 定時上傳傳感器數據,上位機需可靠解析數據幀。本文詳細講解如何在 C# 中使用 Socket.BeginReceive 實現異步接收,並通過幀頭(0xAA, 0x55)校驗提取有效數據,解決粘包、半包問題。

數據幀格式

單片機每秒發送一幀:0xAA, 0x55, 數據1, 數據2,共 4 字節。上位機需判斷前兩字節為幀頭,才提取後兩字節作為有效數據。

異步接收核心代碼

private byte[] m_receiveBuffer = new byte[1024];
private Socket sock;

public void StartReceive() {
    sock.BeginReceive(m_receiveBuffer, 0, m_receiveBuffer.Length, 0, ReceiveCallBack, null);
}

private void ReceiveCallBack(IAsyncResult ar) {
    try {
        int received = sock.EndReceive(ar);
        if (received > 0) {
            ProcessData(m_receiveBuffer, received);
        }
        sock.BeginReceive(m_receiveBuffer, 0, m_receiveBuffer.Length, 0, ReceiveCallBack, null);
    } catch (Exception ex) {
        // 處理異常,如連接斷開
    }
}

數據處理邏輯:幀頭校驗與緩衝區管理

由於 TCP 是流式協議,可能出現粘包(多幀合一)或半包(一幀分多次到達),必須維護一個全局緩衝區:


private List _buffer = new List();

private void ProcessData(byte[] data, int length) {
    _buffer.AddRange(data.Take(length));
    
    while (_buffer.Count >= 4) {
        if (_buffer[0] == 0xAA && _buffer[1] == 0x55) {
            // 找到完整幀
            byte d1 = _buffer[2];
            byte d2 = _buffer[3];
            HandleValidFrame(d1, d2);
            _buffer.RemoveRange(0, 4);
        } else {
            // 幀頭錯誤,丟棄第一字節,繼續尋找
            _buffer.RemoveAt(0);
        }
    }
}

private void HandleValidFrame(byte data1, byte data2) {
    // 合成數據,如 data1 << 8 | data2
    int value = (data1 << 8) | data2;
    // 更新 UI(需 Invoke)
    this.Invoke((Action)(() => {
        label6.Text = $"數據1: {data1:X2}, 數據2: {data2:X2}, 合成: {value}";
    }));
}

關鍵點總結

  • 異步循環:EndReceive 後必須再次調用 BeginReceive 保持接收
  • 緩衝區管理:使用 List 動態拼接、截取,處理粘包/半包
  • 幀同步:幀頭錯誤時逐字節滑動窗口尋找下一幀頭
  • 線程安全:UI 更新必須通過 Invoke 或 BeginInvoke

優化建議

作者提到「延時問題」,可考慮:

  1. 增加心跳機制檢測連接狀態
  2. 使用 SocketAsyncEventArgs 替代 APM 模式,提高性能
  3. 添加數據校驗(如 CRC)提高可靠性
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved