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
[68275] Re:Re:Indy UDP 서버 전송지연에 대한 질문
수야!╋ [sooya23] 1465 읽음    2012-09-27 15:05
정보가 부족했군요.
코딩이 잘못됬다고 믿기 싫어서 그랬나봅니다. 죄송합니다.

통신환경은 192.168대를 사용하는 내부통신입니다.

코딩부분은

클래스로 인디 UDP 서버를 포장했습니다.
인디서버는 new한 이후 DefaultPort, Bindings 와 OnUDPRead를 제외한 모든 프로퍼티엔 손대지 않았습니다.
그리고 전송하는 함수는 다음과 같습니다.
bool __fastcall TUDPServerObject::SendBytes( IN AnsiString i_strIP, IN const int &i_nPort, IN TBytes i_ABytes )
{
    bool bReturnValue = false;

    try
    {
        m_pUDPConnection->SendBuffer(i_strIP, i_nPort, i_ABytes );

        bReturnValue = true;
    }  // end of try
    catch (...)
    {
        bReturnValue = false;
    }  // end of catch
    return bReturnValue;
}
//---------------------------------------------------------------------------
위 클래스를 상속받안 클래스를 사용하는데 명칭은 TUDPServerControl 입니다.
그리고 전송을 위해 TUDPSender라는 클래스를 만들었구요
전송하는 함수는 아래와 같습니다.
bool TUDPSender::Send( IN AnsiString i_strIP, IN unsigned short i_nPort, IN TBytes &i_Bytes )
{
    if( !UDPServerControl )
        return false;

    bool bReturnValue = false;
    UDPServerControl->m_CriticalSectionForSend.Enter();

    try
    {
        bReturnValue = UDPServerControl->SendBytes( i_strIP, i_nPort, i_Bytes );
    }
    catch(...)
    {
    }

    UDPServerControl->m_CriticalSectionForSend.Leave();

    return bReturnValue;
}

//---------------------------------------------------------------------------
m_CriticalSectionForSend는 크리티컬섹션을 클래스화 시킨것입니다.

마지막으로
전송하는 함수입니다.
bool TPacket_UDP_0x07_0x15::Send(    IN unsigned char    i_cGubun, IN AnsiString        i_strDate )
{
    AdoneTickCounter TickCounter;
    TickCounter.Check();
    TProcessLogAdder ProcessLogAdder;
    AnsiString strLog;

    // 패킷을 보낼 위치 찾기
    AdoneList< TSocketCommunication * >    listSocketCommunication;
    SocketCommunicationManager->m_CSGetSocket.Enter();
    SocketCommunicationManager->GetSocketCommunicationData(    AnsiString().sprintf( "%02X", m_ST_UDP_PROTOCOL_0x07_0x15.cOPCode_Type ),
                                                            AnsiString().sprintf( "%02X", m_ST_UDP_PROTOCOL_0x07_0x15.cOPCode_Kind ),
                                                            &listSocketCommunication );
    SocketCommunicationManager->m_CSGetSocket.Leave();

    strLog.sprintf(    "TPacket_UDP_0x07_0x15 - 보낼 위치 찾기 %d 개 ( %d ms )\r\n", listSocketCommunication.Size(), TickCounter.Check() );
    ProcessLogAdder.Add( strLog );

    if( listSocketCommunication.IsEmpty() )
        return false;

    // 해더
    m_ST_UDP_PROTOCOL_0x07_0x15.cPacketSeq    = m_cPacketSeq++;
    m_ST_UDP_PROTOCOL_0x07_0x15.cMsgCL        = MSGCL_SEND_SINGLE;
    m_ST_UDP_PROTOCOL_0x07_0x15.cResFlag    = RESFLAG_DONT_ACK;
    m_ST_UDP_PROTOCOL_0x07_0x15.cTaskSeqNo    = IniFileManager->ProcessSeq;

    if( i_strDate.Length() > 14 )
        return false;

    m_ST_UDP_PROTOCOL_0x07_0x15.cGubun    = i_cGubun;
    memcpy( m_ST_UDP_PROTOCOL_0x07_0x15.szDate, i_strDate.c_str(), i_strDate.Length() );

    // 전송 버퍼에 복사
    m_SendData.Length = sizeof( ST_UDP_PROTOCOL_0x07_0x15 );
    memcpy( &m_SendData[0], &m_ST_UDP_PROTOCOL_0x07_0x15, sizeof( ST_UDP_PROTOCOL_0x07_0x15 ) );

    strLog.sprintf(    "TPacket_UDP_0x07_0x15 - 전송 데이터 복사 ( %d ms )\r\n", TickCounter.Check() );
    ProcessLogAdder.Add( strLog );

    AdoneTickCounter TickCounterSend;
    TickCounterSend.Check();

    // 전송
    for(    TSocketCommunication *pSocketCommunication = listSocketCommunication.GetHead();
            !listSocketCommunication.IsEnd();
            pSocketCommunication = listSocketCommunication.GetNext() )
    {
        try
        {
            // 전송 위치 정보
            m_strIP = pSocketCommunication->m_strIPAddress;
            m_nPort = pSocketCommunication->m_nPort;

            // 전송
            TUDPSender UDPSender;
            UDPSender.Send( m_strIP, m_nPort, m_SendData );

            TFileLogAdder FileLogAdder;
            strLog.sprintf(    "[%s]%s:%d ( 구분 : %c, Date : %s ) 송신 - %d ms\r\n",
                            Now().FormatString( "YYYY-MM-DD HH:NN:SS" ).c_str(),
                            m_strIP.c_str(),
                            m_nPort,
                            i_cGubun,
                            i_strDate.c_str(),
                            TickCounterSend.Check() );
            FileLogAdder.Add(    AnsiString().sprintf( "%d\\UDP_0x07_0x15.UDP", pSocketCommunication->m_nToProcessID ),
                                strLog.c_str(), strLog.Length(),
                                IniFileManager->m_bWriteFileUDP_0x07_0x15,
                                IniFileManager->m_bWriteConsoleUDP_0x07_0x15 );
        }
        catch(...)
        {
            strLog.sprintf(    "[%s]%s:%d ( 구분 : %c, Date : %s ) 송신실패 - %d ms\r\n",
                            Now().FormatString( "YYYY-MM-DD HH:NN:SS" ).c_str(),
                            m_strIP.c_str(),
                            m_nPort,
                            i_cGubun,
                            i_strDate.c_str(),
                            TickCounterSend.Check() );
            TFileLogAdder FileLogAdder;
            FileLogAdder.Add(    AnsiString().sprintf( "%d\\UDP_0x07_0x15.UDP", pSocketCommunication->m_nToProcessID ),
                                strLog.c_str(), strLog.Length(),
                                IniFileManager->m_bWriteFileUDP_0x07_0x15,
                                IniFileManager->m_bWriteConsoleUDP_0x07_0x15 );
        }

        ::Sleep( 1 );
    }

    strLog.sprintf(    "TPacket_UDP_0x07_0x15 - 전송 처리 완료 ( %d ms )\r\n", TickCounter.Check() );
    ProcessLogAdder.Add( strLog );

    return true;
}
//-----------------------------------------------------------------------------
이렇게 처리가 끝납니다. 위 함수는 클래스로써 생성해서 사용하는 구조입니다.

위 함수의 호출위치는 쓰래드에 위치해 있습니다.

위 함수가 호출되면 로컬내에 7곳에 전송이 일어납니다.

아래는 로그파일의 내용인데요

정상일때의 로그
[2012-09-27 13:45:59]
TPacket_UDP_0x07_0x15 - 보낼 위치 찾기 7 개 ( 0 ms )
[2012-09-27 13:45:59]
TPacket_UDP_0x07_0x15 - 전송 데이터 복사 ( 0 ms )
[2012-09-27 13:45:59]
TPacket_UDP_0x07_0x15 - 전송 처리 완료 ( 109 ms )

비정상일때의 로그
[2012-09-27 13:50:59]
TPacket_UDP_0x07_0x15 - 보낼 위치 찾기 7 개 ( 0 ms )
[2012-09-27 13:50:59]
TPacket_UDP_0x07_0x15 - 전송 데이터 복사 ( 0 ms )
[2012-09-27 13:52:08]
TPacket_UDP_0x07_0x15 - 전송 처리 완료 ( 68875 ms )


클라이언트에 받고 말고를 떠나서 보내는데 시간이 저렇게 늘어져버립니다.

정보가 부족한 부분이 있나요?

기다리겠습니다.

pro 님이 쓰신 글 :
: 로컬에서도 그렇다는건지 안나와있고
: 소스코드 없이 답변이 가능하지 않을거 같은데요?
:
:
: 수야!╋ 님이 쓰신 글 :
: : 안녕하세요
: :
: : 수야!╋ 입니다.
: :
: : 또 아쉬울때 찾아와버렸네요.
: :
: : 늘 답변주시는 분들에게 감사드리고 있습니다.
: :
: : 개발환경
: : Win7 32 bit
: : CodeGear 2009
: :
: : 운영환경
: : Win 2003 Server
: :
: : 그런데 UDP서버에서 Send를 할때 평소엔  10sm 정도 소요로 잘 돌다가 어느순간부터
: :
: : 작게는 9초에서 심하게는 3분이상도 걸립니다.
: :
: : 5분마다 30byte 이하 크기로 7회씩 전송하며 전송후 Sleep( 1 )을 주어서 전송하고 있습니다.
: :
: : 비슷한 경험을 하셨거나 증상을 아시는 분이 계시다면 답변 부탁드리겠습니다.
: :
: : - 추가내용
: : 네트웍상 다른 클라이언트가 수신하는 시간이 아닌 UDP Server에서 Send를 호출해서 완료하는 시간입니다.

+ -

관련 글 리스트
68262 Indy UDP 서버 전송지연에 대한 질문 수야!╋ 1212 2012/09/27
68272     Re:Indy UDP 서버 전송지연에 대한 질문 pro 1347 2012/09/27
68275         Re:Re:Indy UDP 서버 전송지연에 대한 질문 수야!╋ 1465 2012/09/27
68286             Re:Re:Re:Indy UDP 서버 전송지연에 대한 질문 pro 2300 2012/09/30
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.