|
정보가 부족했군요.
코딩이 잘못됬다고 믿기 싫어서 그랬나봅니다. 죄송합니다.
통신환경은 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를 호출해서 완료하는 시간입니다.
|