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

C 語言 Socket 二進制圖片傳輸:內存指針與長度核心原理

     編輯:程式設計綜合問答

核心概念

Socket 傳輸本質:**發送內存中連續字節序列**。無論文本、結構體、圖片、視頻,對 Socket 都是 char* (或 void*) + 長度。

發送端核心代碼

int sendImage(int sockfd, const char *filepath) {
    // 1. 讀取文件到內存
    FILE *fp = fopen(filepath, "rb");
    if (!fp) return -1;
    fseek(fp, 0, SEEK_END);
    long fsize = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char *buffer = malloc(fsize);
    fread(buffer, 1, fsize, fp);
    fclose(fp);

    // 2. 發送長度 (網絡字節序)
    uint32_t netLen = htonl(fsize);
    send(sockfd, &netLen, 4, 0);  // 固定 4 字節長度頭

    // 3. 發送數據 (分包循環)
    long sent = 0;
    while (sent < fsize) {
        int n = send(sockfd, buffer + sent, fsize - sent, 0);
        if (n <= 0) { free(buffer); return -1; }
        sent += n;
    }
    free(buffer);
    return 0;
}

接收端核心代碼

int recvImage(int sockfd, const char *savePath) {
    // 1. 接收長度頭
    uint32_t netLen;
    int n = recv(sockfd, &netLen, 4, MSG_WAITALL);
    if (n != 4) return -1;
    long fsize = ntohl(netLen);

    // 2. 分配內存並接收數據
    char *buffer = malloc(fsize);
    long received = 0;
    while (received < fsize) {
        n = recv(sockfd, buffer + received, fsize - received, 0);
        if (n <= 0) { free(buffer); return -1; }
        received += n;
    }

    // 3. 寫入文件
    FILE *fp = fopen(savePath, "wb");
    fwrite(buffer, 1, fsize, fp);
    fclose(fp);
    free(buffer);
    return 0;
}

關鍵點總結

環節關鍵
文件讀取fopen(..., "rb") 二進制模式,fread 一次性讀入
長度協議固定 4/8 字節頭 + htonl/ntohl 網絡序,雙端解析一致
分包處理send/recv 返回實際字節數,**必須循環**直到完成
內存管理大文件考慮分塊讀寫 (mmap/文件映射) 避免 OOM
結構體傳輸同樣原理:send(sock, &struct, sizeof(struct), 0),但需處理對齊、端序、指針無效化

進階:大文件分塊傳輸 (避免大內存分配)

// 發送端:邊讀邊發
while ((n = fread(buf, 1, BUFSIZE, fp)) > 0) {
    sendAll(sockfd, buf, n);
}

// 接收端:邊收邊寫
while (received < fsize) {
    n = recv(sockfd, buf, BUFSIZE, 0);
    fwrite(buf, 1, n, fp);
    received += n;
}

與結構體傳輸的關係

**完全相同原理**。結構體只是特定格式的二進制數據。區別在於:

  • 結構體需關注 #pragma pack 對齊、端序轉換、指針字段無法直接傳輸。
  • 圖片/文件是無格式字節流,只需長度協議。

總結

Socket 傳輸二進制圖片 = **讀文件入內存 → 發長度頭 → 循環發數據**。核心就是一個指針、一個長度、一個循環。結構體傳輸同理,額外處理對齊與端序。

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