취미생활
[C] Union으로 패킷 데이터 형변환하기 본문
TCP/IP 통신으로 데이터 패킷을 주고 받으면 8bit 데이터 배열을 특정 자료형으로 변경해야 하는 일이 생긴다.
이러한 경우 union(공용체) 으로 쉽게 형변환하여 데이터를 볼 수 있다.
#include <stdio.h>
#include <string.h>
union packet // union 선언
{
int t_int;
char t_char[4];
float t_float;
};
void tcp_something(packet* target){
const int val = 143;
const int max = sizeof(packet);
snprintf(target->t_char, sizeof(target), "123"); // 데이터 입력 지점
}
int main() {
packet s;
tcp_something(&s);
printf("%d\n", s.t_int); // integer 출력
printf("%s\n", s.t_char); // char 출력
printf("%f\n", s.t_float); // float 출력
return 0;
}
tcp_something 부분은 볼 필요 없다.
단순하게 데이터를 써주는 부분이다.
우리가 확인해야 할 부분은 공용체의 선언과 printf 부분이다.
union packet // union 선언
{
int t_int;
char t_char[4];
float t_float;
};
union 선언은 struct와 동일하지만,
메모리 구조는 완전히 다르다.
struct 같은 경우 선언된 자료형들이 배열처럼 나열되는 방식이라면
union 의 경우 자료형의 메모리 최대 값 만큼 할당을 해둔 뒤, 자료형 별로 메모리 읽는 법을 바꾸는 것이다.
메모리 구조는 아래 그림을 생각하면 될 듯
union packet
{
int t_int;
char t_char[4];
float t_float;
};
struct packet
{
int t_int;
char t_char[4];
float t_float;
};


공용체는 잘 사용하진 않지만
Tcp/ip 같이 Byte 데이터를 읽어서 특정 자료형으로 바꿔줘야 하는 경우 사용한다.
void tcp_something(packet* target){
const int val = 143;
const int max = sizeof(packet);
snprintf(target->t_char, sizeof(target), "123");
}
해당 코드는 예시 코드에 있는 tcp/ip 통신에서 어떤 데이터가 왔을 경우를 상정한다.
만약 tcp/ip 에서 상대편이 문자열 123을 보낼 경우,
이를 자료형 별로 출력하면 아래와 같다.

예시와 같이 문자열 123을 보낼 경우 데이터는 string으로 자료형을 잡아야 한다.
Int와 Float는 문자열 123의 Ascii 값인 0x21, 0x22, 0x23 으로 데이터를 출력한다.
그렇다면 만약,
Int 나 Float로 데이터를 전송하는 경우에는 어떤 식으로 보일까?
void tcp_something(packet* target){
const int val = 143;
const int max = sizeof(packet);
//snprintf(target->t_char, sizeof(target), "123");
target->t_float = 0.1240;
}
tcp 값으로 t_float 값을 0.1240으로 입력한다고 상정하고 데이터를 출력해보자

이 경우 float는 정상 값을 출력하지만, 이외의 데이터는 쓰레기 값이 잡히게 된다.
위 예시에서 보는 것과 같이
union은 입력받은 byte 값을 자료형에 따라 다르게 사용할 수 있다.
해당 기능은 C 또는 C++에서 tcp/ip 패킷 데이터 처리할 때 굉장히 편했다.
특히,
패킷 데이터가 정해져있는 사이즈가 아닌 경우 굉장히 좋았다.
패킷 처리 중에 또 다른 방법이 생긴다면 다시 포스트 올려보도록 하겠다.
'컴퓨터 > C' 카테고리의 다른 글
[C] 엄청 간단한 Queue 구현 (0) | 2023.06.10 |
---|---|
[C] Double Linked List 구현 (0) | 2023.04.05 |