int DataProcess(BYTE *Buffer,DWORD Start, DWORD Size, int *PicesByte)
{
#pragma pack(push,1)
struct TPacket
{
WORD PacketSize;
DWORD CheckSum;
DWORD Seq;
DWORD From;
DWORD To;
WORD Length;
}*Packt;
#pragma pack(pop)
DWORD p; // 현재포인트
DWORD pp;// 이전포인트
DWORD sm;// 스타트마크위치
WORD ps; //페킷사이즈
p=Start;
while(1)
{
// 이전포인트 설정
pp=p;
// 스타트마크를 검색한다
for(; p < Size; p++)
{
// 스타트마크 발견
if(Buffer[p] == '[')
{
sm=p;
break;
}
}
// 스타트마크를 발견하지못했다
if(p >= Size)
{
// 정상종료로 간주
return 0;
}
// 페킷사이즈 얻을만한 길이도 안된다
if(Size-p <= 3)
{
// 조각난바이트계산
*PicesByte=Size-pp;
return 0;
}
// 페킷구조체 셋팅
Packt=(TPacket*)(Buffer+p+1);
// 모든데이터가 버퍼내에 존재하는지 확인
if(p+Packt->PacketSize+2 > Size)
{
// 조각난바이트계산
*PicesByte=Size-pp;
return 0;
}
// 엔드마크 확인
if(Buffer[p+Packt->PacketSize+1] != ']')
{
// 조각난바이트계산
*PicesByte=Size-pp;
return 0;
}
// 조각나지않고 모든 데이터가 버퍼안에 있다
// 체크섬이 맞다 임시로0 을채워둠
if(Packt->CheckSum == 0)
{
char Temp[3000];
memcpy(Temp,Buffer+p+sizeof(TPacket)+1,Packt->Length);
Temp[Packt->Length]=0;
printf("%s\n",Temp);
p+=Packt->PacketSize+2;
}else {
// 체크섬이 틀리다
// 페킷해더만큼 데이터 버리고 진행
p+=sizeof(TPacket)+1;
}
}
return 0;
}
int FileProcess(void)
{
HANDLE hFile;
HANDLE fileMapping;
BYTE *Base;
LARGE_INTEGER FIleSize;
ULONGLONG BytesLeft;
int ReadByte;
LARGE_INTEGER Current;
int PicesByte;
DWORD Offset;
// 파일을연다 메모리맵드파일에 최적화된 플레그를사용한다
hFile = CreateFile(
"SMS_1.dat",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING
,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile error\n");
return 1;
}
// 파일매핑
fileMapping=CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL);
if(!fileMapping)
return -1;
GetFileSizeEx(hFile,&FIleSize);
BytesLeft=FIleSize.QuadPart;
Current.QuadPart=0;
Offset=0;
while(BytesLeft > 0)
{
// 처리하고남은 조각
PicesByte=0;
// 읽을바이트 결정
ReadByte=BytesLeft > 1048576 ? 1048576: BytesLeft;
// 남은바이트 설정
BytesLeft-=ReadByte;
// 포인터 얻어내기
Base=(BYTE*)MapViewOfFile(
fileMapping,
FILE_MAP_READ,
Current.HighPart,Current.LowPart,
ReadByte );
if(!Base)
{
// 에러날일없겠지만 이리오로면 미친다
MessageBox(NULL,"1err","1 err",0);
return -1;
}
// 메모리블럭을 처리한다
DataProcess(Base,Offset,ReadByte,&PicesByte);
// 포인터반환
UnmapViewOfFile(Base);
// 남은 바이트가 없으면 끝
if(BytesLeft <= 0)
{
break;
}
// 조각난 바이트를 다시읽기위해 AllocationGranularity 단위위로 위치를얻는다
ULONGLONG AGSeg=(Current.QuadPart+ReadByte-PicesByte)/SystemInfo.dwAllocationGranularity*SystemInfo.dwAllocationGranularity;
// 도중에끊어진 페킷의 시작점의 AGSeg 기준의 오프셋
Offset=(Current.QuadPart+ReadByte-PicesByte)-AGSeg;
// 현재진행한 메모리위치를 설정
Current.QuadPart=AGSeg;
// 남은바이트수를 구한다
BytesLeft=FIleSize.QuadPart-Current.QuadPart;
}
return -1;
}
UDP페킷같은 데이터를 파일에 쭉쭉쭉 저장해놓은것을
메모리맵드파일을 이용해 1MB단위로 읽어서 처리하는소스임니다 (테스트 1MB 실사용시는 1GB)
ㅋㅋㅋ; 잘되는거같은데 좀더세심한 검증을더해야 안심될듯..
오늘 목표를 달성해서 뿌듯하다
드디어 메모리맵드파일 한번써봤음 AllocationGranularity 단위로 읽는특성이 잇어서 간만에
오프셋 구하면서 산수능력을 시험받음 쫄깃했음..
이거슨 마치 DOS때 세그먼트크기 64k 한계랑 비슷한 귀차니즘과 코딩경험을 되살림
관심있는분은 MMF 부분만 참고하세연 AllocationGranularity 단위처리가 아주빡침
댓글 0