C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[65827] 인디10에서 Stream으로 받을 때 패킷이 깨지는건..
용맨소녀 [doyongid] 1031 읽음    2011-12-29 18:28
패킷을 받아서 자신을 포함한 다른 사람들에게 뿌리는 서버입니다. 간단하다면 간단한 구조라고 할 수 있는데요..ㅡ.ㅡ

잘 가다가 어쩌다 한 번씩 헤더에 패킷이 깨져서 옵니다. 쓰레기값이 섞여서 들어오는데, 값이 밀리는것 같아보였어요..

이런저런 코드 다 빼고 최대한 간단하게 해놔도 한 번씩 패킷이 깨져서 와요..
무시하고 버퍼를 비우긴 하는데, 그러다가 불안정해져서 튕기고 그럽니다..

사람당 매초 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(...)
{
		}
	}
}


+ -

관련 글 리스트
65827 인디10에서 Stream으로 받을 때 패킷이 깨지는건.. 용맨소녀 1031 2011/12/29
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.