카테고리 없음

c++ 바이너리 이미지 송신 코드분석

joo_coding 2025. 6. 26. 09:12
// 클라이언트에게 이미지 파일을 바이너리로 전송하는 함수
bool send_image(int client_sock, const std::string& filepath) {
    // [1] 파일 경로가 비어있으면 에러 반환
    if (filepath.empty()) {
        std::cerr << "[ERROR] send_image: 경로가 비어 있습니다." << std::endl;
        return false;
    }

    // [2] 파일을 바이너리 모드로 열기
    FILE* file = fopen(filepath.c_str(), "rb");
    if (!file) {
        std::cerr << "[ERROR] 파일 열기 실패: " << filepath << std::endl;
        return false;
    }

    // [3] 파일의 전체 크기를 구하기 위해 끝으로 이동
    fseek(file, 0, SEEK_END);
    int32_t filesize = static_cast<int32_t>(ftell(file));  // 현재 위치 = 파일 크기
    rewind(file);  // 파일 포인터 처음으로 되돌리기

    std::cout << "[INFO] 이미지 크기 (바이트): " << filesize << std::endl;

    // [4] 파일 크기를 4바이트 리틀 엔디안 형식으로 분해
    uint8_t size_bytes[4];
    size_bytes[0] = filesize & 0xFF;
    size_bytes[1] = (filesize >> 8) & 0xFF;
    size_bytes[2] = (filesize >> 16) & 0xFF;
    size_bytes[3] = (filesize >> 24) & 0xFF;

    // [5] 먼저 이미지 크기 4바이트 전송
    send(client_sock, size_bytes, 4, 0);

    // [6] 이미지 데이터 본문 전송 (1024바이트 단위로)
    char buffer[1024];
    size_t bytes_read;
    while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) {
        send(client_sock, buffer, bytes_read, 0);
    }

    // [7] 파일 닫기 및 성공 메시지
    fclose(file);
    std::cout << "[INFO] 이미지 전송 완료: " << filepath << std::endl;

    return true;
}

✅ 작동 원리 요약

이 함수는 TCP 통신을 통해 서버에서 클라이언트로 이미지를 전송하기 위한 정형화된 프로토콜을 구현한 것입니다. 작동 과정은 다음과 같습니다:

  1. 파일 경로 검증 및 열기
    • filepath가 비어있거나 존재하지 않으면 실패 처리.
    • fopen(filepath, "rb")를 통해 이미지 파일을 바이너리 읽기 모드로 엶.
  2. 이미지 크기 전송 (4바이트)
    • ftell을 사용해 이미지 전체 바이트 크기를 구함.
    • 이 크기를 4바이트 리틀엔디안 포맷으로 분해.
    • 클라이언트는 이 4바이트를 수신하여 몇 바이트를 수신해야 할지 판단함 (receiveImageData()에서 처리됨).
  3. 이미지 데이터 전송
    • fread를 사용해 1024바이트씩 읽어와 send로 전송.
    • 끝까지 전송되면 종료.
  4. 정상 종료
    • 파일 닫고 로그 출력 후 true 반환.

✅ 이 함수와 클라이언트와의 연동 방식

이 서버 함수는 다음과 같은 클라이언트 구조와 연결되어 있습니다:

  • 클라이언트가 JSON으로 show_image 요청 → 서버에서 send_image() 실행
  • 클라이언트는 4바이트(파일 크기) → 이어서 바디 데이터 수신 → QImage 변환 → UI에 띄움 (Page4_ShopList::receiveImageData()에서 처리)