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

MFC UDP通信接收截斷:Unicode項目中char數組導致單字節接收解決方案

     編輯:程式設計綜合問答

問題現象

MFC `CAsyncSocket::ReceiveFrom` 接收 UDP 數據,預期接收字符串,實際僅收到**第一個字節**(如發送 "Hello",僅收到 'H')。

根本原因

項目屬性 **Character Set = Unicode** (默認),導致:

  • `CString` 內部存儲 `wchar_t` (2字節/字符)
  • 發送時 `SendTo(str, str.GetLength())` 發送的是 **字符數** 而非字節數,實際發送字節數 = 字符數 × 2
  • 接收端定義 `char s[256]` (單字節字符數組),`ReceiveFrom(s, sizeof(s))` 按字節接收
  • Unicode 字符 'H' 編碼為 `0x0048`,低字節 `0x48` ('H')、高字節 `0x00` (`\0`),`char` 數組遇到 `\0` 視為字符串結束,顯示截斷

解決方案:發送端轉為 MBCS (UTF-8/ANSI)

void CChatDlg::OnBnClickedSendButton() {
    CString str;
    GetDlgItemText(IDC_SEND_EDIT, str);
    
    // Unicode (wchar_t) → UTF-8 (char*)
    int len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
    char* utf8 = new char[len];
    WideCharToMultiByte(CP_UTF8, 0, str, -1, utf8, len, NULL, NULL);
    
    m_sock.SendTo(utf8, len - 1, PORT, sIP); // 發送實際字節數,不含結束符
    delete[] utf8;
}

接收端對應處理

void CChatDlg::OnReceive(int nErrorCode) {
    char s[1024];
    CString sIP; UINT nPort;
    int nRecv = m_sock.ReceiveFrom(s, sizeof(s) - 1, sIP, nPort);
    if (nRecv > 0) {
        s[nRecv] = '\0';
        // UTF-8 → Unicode 顯示
        int len = MultiByteToWideChar(CP_UTF8, 0, s, nRecv, NULL, 0);
        wchar_t* wbuf = new wchar_t[len + 1];
        MultiByteToWideChar(CP_UTF8, 0, s, nRecv, wbuf, len);
        wbuf[len] = L'\0';
        CString str(wbuf);
        delete[] wbuf;
        // 顯示到編輯框...
    }
}

替代方案:項目改為 MBCS

項目屬性 → General → Character Set → **Use Multi-Byte Character Set**。但不推薦,現代 Windows 開發應統一 Unicode 內部,邊界處理編碼轉換。

關鍵函數速查

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數用途關鍵參數
WideCharToMultiByteUnicode → ANSI/UTF-8CP_UTF8 / CP_ACP
MultiByteToWideCharANSI/UTF-8 → UnicodeCP_UTF8 / CP_ACP
CString::GetLength返回字符數(非字節數)Unicode下每字符2字節
sizeof(buffer)返回字節數char[256] → 256