본 수업에 들어가기 전 한 가지 질문
struct PKT_S_TEST
{
uint32 hp; // 4
uint64 id; // 8
uint16 attack; // 2
}
총 14바이트가 사용될까??
-> 24바이트가 사용된다
Why?
64bit운영체제 아래에서는 8바이트 단위로 접근이 속도가 빠르다
따라서 8바이트 단위로 더미데이터를 넣어준다
| hp(4) | dummy(4) |
| id(8) |
| attack(2) | dummy(6) |
따라서 컴파일러에게 1바이트 단위로 넣어달라 알려줘야한다
#pragma pack(1)
struct PKT_S_TEST
{
uint32 hp; // 4
uint64 id; // 8
uint16 attack; // 2
}
#pragma pack
- 지금까지 패킷관리의 문제점을 찾아보면
- (서버/클라) 패킷의 정보를 파일에서 관리
struct S_TEST
{
uint64 id;
uint32 hp;
uint16 attack;
// 가변 데이터
// 1) 문자열 (ex. name)
// 2) 그냥 바이트 배열 (ex. 길드 이미지)
// 3) 일반 리스트
vector<BuffData> buffs;
wstring name;
};
- 패킷이 추가될때마다 함수가 추가되어야 하고 실수의 여지가 있다
void ClientPacketHandler::Handle_S_TEST(BYTE* buffer, int32 len)
{
BufferReader br(buffer, len);
PacketHeader header;
br >> header;
uint64 id;
uint32 hp;
uint16 attack;
br >> id >> hp >> attack;
cout << "ID: " << id << " HP : " << hp << " ATT : " << attack << endl;
vector<BuffData> buffs;
uint16 buffCount;
br >> buffCount;
buffs.resize(buffCount);
for (int32 i = 0; i < buffCount; i++)
{
br >> buffs[i].buffId >> buffs[i].remainTime;
}
cout << "BufCount : " << buffCount << endl;
for (int32 i = 0; i < buffCount; i++)
{
cout << "BufInfo : " << buffs[i].buffId << " " << buffs[i].remainTime << endl;
}
wstring name;
uint16 nameLen;
br >> nameLen;
name.resize(nameLen);
br.Read((void*)name.data(), nameLen * sizeof(WCHAR));
wcout.imbue(std::locale("kor"));
wcout << name << endl;
}
1. (서버/클라) 패킷의 정보를 파일에서 관리
패킷의 정보를 공통으로 관리해보자
<?xml version="1.0" encoding="utf-8"?>
<PDL>
<Packet name="S_TEST" desc="테스트 용도">
<Field name="id" type="uint64" desc=""/>
<Field name="hp" type="uint32" desc=""/>
<Field name="attack" type="uint16" desc=""/>
<List name="buffs" desc="">
<Field name="buffId" type="uint64" desc=""/>
<Field name="remainTime" type="float" desc=""/>
</List>
</Packet>
</PDL>
아직은 xml 자체를 사용하지 않고 이런식으로 포멧을 만들고 툴을 이용하여 파싱할 예정