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

MFC Socket 讀取傳感器返回數據:阻塞/非阻塞循環讀取

     編輯:程式設計綜合問答

場景

MFC 應用通過 TCP Socket 連接傳感器,已發送指令,需讀取返回數據。

核心 API

MFC CSocket/CAsyncSocket 封裝了底層 recv(),直接用:

// 阻塞模式(預設)
char buffer[1024];
int nRead = socket.Receive(buffer, sizeof(buffer));  // 返回實際讀取字節數,0=連接關閉,-1=錯誤
if (nRead > 0) {
    // 處理 buffer[0..nRead-1]
}

// 非阻塞/異步模式(CAsyncSocket)
// 需重寫 OnReceive(int nErrorCode)
void CMySocket::OnReceive(int nErrorCode) {
    if (nErrorCode == 0) {
        char buf[1024];
        int len = Receive(buf, sizeof(buf));
        if (len > 0) ProcessData(buf, len);
    }
    CAsyncSocket::OnReceive(nErrorCode);
}

關鍵點:應用層協議解析

TCP 無消息邊界,**必須自行實現「讀齊一包」邏輯**:

  1. 定長包頭:前 4 字節標識包體長度(網絡序)。
  2. 循環讀取:
    // 1. 讀包頭 4 字節
    int headerLen = 0;
    while (headerLen < 4) {
        int n = socket.Receive(((char*)&pkgLen) + headerLen, 4 - headerLen);
        if (n <= 0) return; // 斷開/錯誤
        headerLen += n;
    }
    pkgLen = ntohl(pkgLen); // 網絡序轉主機序
    
    // 2. 讀包體
    std::vector<char> body(pkgLen);
    int bodyRead = 0;
    while (bodyRead < pkgLen) {
        int n = socket.Receive(&body[bodyRead], pkgLen - bodyRead);
        if (n <= 0) return;
        bodyRead += n;
    }
    ProcessPacket(body);

MFC 類選擇

  • CSocket:同步阻塞,適合工作線程中簡單收發。
  • CAsyncSocket:異步通知,適合 UI 線程避免卡死,需手動處理粘包/分包。

無論哪類,**應用層協議解析(定長包頭/分隔符/長度前綴)是核心**,不可依賴單次 Receive 返回完整業務包。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved