패킷을 받아서 자신을 포함한 다른 사람들에게 뿌리는 서버입니다. 간단하다면 간단한 구조라고 할 수 있는데요..ㅡ.ㅡ
잘 가다가 어쩌다 한 번씩 헤더에 패킷이 깨져서 옵니다. 쓰레기값이 섞여서 들어오는데, 값이 밀리는것 같아보였어요..
이런저런 코드 다 빼고 최대한 간단하게 해놔도 한 번씩 패킷이 깨져서 와요..
무시하고 버퍼를 비우긴 하는데, 그러다가 불안정해져서 튕기고 그럽니다..
사람당 매초 10-20번 송신을 받거든요.. 그걸 모든 사람한테 뿌리면요.. 사람당 200KB/Sec 정도 됩니다. 2명이 들어오면 사람당 500KB/Sec 정도고요..
일단, 스트림 전송을 하는데요.. 스트림을 하나만 만들면 송신중에 또 적재를 못하니까 2개를 만들어서 스위칭하면서 패킷을 적재하고 보내고 그러고 있어요..
송신은 RecvData()안에서 SendPacket()을 호출하고 있고요..
아래에서 문제되는 부분이 있을까요? 머리 빠지겠습니다..ㅡ.ㅡ
// 패킷 처리부
void __fastcall TServer::OnExecute(TIdContext *pContext)
{
SPacketHeader stHeader;
BYTE Buffer[BUFFER_SIZE];
TMemoryStream *RecvStream = new TMemoryStream;
TConnect *lpConnect = NULL;
__try
{
__try
{
Sleep(1);
if(!pContext || !pContext->Connection || !pContext->Connection->Connected())
return;
if(!pContext->Connection->IOHandler->Readable())
return;
// 헤더 받기
pContext->Connection->IOHandler->ReadStream(RecvStream, sizeof(SPacketHeader), false);
CopyMemory(&stHeader, (SPacketHeader *)((BYTE *)RecvStream->Memory), sizeof(SPacketHeader));
// 패킷 받기
pContext->Connection->IOHandler->ReadStream(RecvStream, stHeader.Size, false);
CopyMemory(Buffer, ((BYTE *)RecvStream->Memory), stHeader.Size);
lpConnect = (TConnect *)pContext->Data;
}
catch(...)
{
pContext->Connection->Disconnect();
}
}
__finally
{
delete RecvStream;
}
Cs->Enter();
__try
{
// 패킷 처리
switch(stHeader.Cmd)
{
case CMD_DATA1:
lpConnect->RecvData1(Buffer);
break;
case CMD_DATA2:
lpConnect->RecvData2(Buffer);
break;
default:
return;
}
}
__finally
{
Cs->Leave();
}
}
// 접속자 송신 스트림에 적재 (위의 TCriticalSection 처리부 내에서만 호출)
void TConnect::SendPacket(DWORD pCmd, void *pBuffer, int pSize)
{
SPacketHeader stHeader;
stHeader.Cmd = pCmd;
stHeader.Size = pSize;
stHeader.Check = pSize - 1;
__try
{
lpPushStream->Position = lpPushStream->Size;
lpPushStream->WriteBuffer(&stHeader, sizeof(SPacketHeader));
if(pBuffer != NULL)
lpPushStream->WriteBuffer(pBuffer, pSize);
}
catch(...)
{
}
}
// 최종 송신
void __fastcall TConnect::Execute(void)
{
while(!Terminated)
{
Sleep(1);
Cs->Enter();
__try
{
if(lpPushStream->Size == 0)
continue;
// 스트림 2개를 교대로 돌리면서 전송할 스트림을 얻어옴
if(lpPushStream == SendStream[0])
{
lpWorkStream = SendStream[0];
lpPushStream = SendStream[1];
}
else
{
lpWorkStream = SendStream[1];
lpPushStream = SendStream[0];
}
}
__finally
{
Cs->Leave();
}
// 패킷 최종 전송
__try
{
if(lpWorkStream->Size > 0)
{
lpWorkStream->Position = 0;
lpContext->Connection->IOHandler->Write(lpWorkStream);
lpWorkStream->Clear();
}
}
catch(...)
{
}
}
}
|