QObject 를 상속 받아 UDP 구현시 다중 sendto 문제
안녕하세요. UDP 통신 중 의도치 않은 결과가 발생해서 질문 드립니다.
QObject 를 상속 받은 UDP 클래스에서 udp 소켓을 생성 하였습니다.
// 소켓을 생성 m_nSock = socket( PF_INET, SOCK_DGRAM, 0); if( -1 == m_nSock) { QMessageBox::information( parent, "UDP", "I cannot build a socket!!"); return; } // 소켓 정보를 완성하고 bind()함수를 호출하여 // 다른 시스템에서 전송되어 오는 자료를 수신할 준비 memset( &m_addrMdp, 0, sizeof( m_addr1)); m_addr1.sin_family = AF_INET; m_addr1.sin_port = htons(MDP_PORT); m_addr1.sin_addr.s_addr = unMdpIp; if( -1 == bind( m_nSock, (struct sockaddr*)&m_addr1, sizeof( m_addr1)) ) { QMessageBox::information( parent, "UDP", "bind error!!"); return; } // 다른 시스템에서 전송되어 오는 자료를 send 준비 memset( &m_addr2, 0, sizeof( m_addr2)); m_addr2.sin_family = AF_INET; m_addr2.sin_port = htons(DCP_PORT); m_addr2.sin_addr.s_addr = unDcpIp; // UDP로부터 수신을 감시하는 QSocketNotifier를 생성 // 그리고 생성한 QSocketNotifier 시그널에 대해 슬롯 연결 m_pSocketNotifier = new QSocketNotifier( m_nSock, QSocketNotifier::Read, parent); connect( m_pSocketNotifier, SIGNAL( activated( int)), this, SLOT( onReceiveFormUdp())); // data 수신 시그널과 data 처리 슬롯 연결 connect( this, SIGNAL( received(char*, int) ), parent, SLOT( onPacketProc(char*, int) ));
receive 부분은 activated 시그널을 onReceiveFormUdp() 함수에서 처리하고
onReceiveFormUDP 에서 received 함수(시그널) 을 호출 하여 onPacketProc 에서 헤더를 참조하여 처리 하도록 하였습니다.
sendto 함수는 m_addr2를 사용하여 send 하는 함수를 만들었습니다.
void CUDP::SendPacketData(char* buffData, int nBuffSize) { sendto( m_nSock, buffData, nBuffSize, 0, ( struct sockaddr*)&m_addr2, sizeof(m_addr2) ); }
여기서 문제점이 send 의 경우 12Hz와 40hz Timer 가 있고 두개의 Timer에서 Send 함수를 호출 합니다.
Qtimer1() 12hz
{
pDUP->SendPacketData(...);
}
QTimer2()40hz
{
pDUP->SendPacketData(...);
}
이 외에도 이벤트 메시지가 발생시 SendPacketData()함수를 호출합니다.
main Thread는 opengl로 화면을 랜더링 하고 있으며,
특정 메시지를 수신 받으면 (1)40hz 송신 데이터의 특정 값을 변경 하고 thread를 생성 하여 데이터를 처리 합니다.
처리중 12hz와 40hz는 계속 해서 송신 중이고 thread 작업이 끝나면 (2)그값을 갱신하여 40hz 메시지에 값을 바꿔 송신합니다.
여기서 문제가.. 수신하는 쪽에서 (1)에 대한 신호가 들어 오면 이후로 12hz 신호가 들어 오지 않고
(2)의 신호가 수신된 후 약 2초 정도 후에 12Hz 값이 들어 온다고 합니다. (약2초는 랜덤)
질문1. QTimer가 다른 Thread( 메인이 아닌 추가 생성된) 동작중 작동하지 않을수 있나요?
질문2. sendTo 호출시 별도의 lock을 구현하지 않았는데 메시지가 겹쳐버리는 현상은 발생하지 않을까요?(12hz와 40hz 만 해도 1초에 몇번의 겹침 이 발생할것 같습니다.)
상대 장비를 모의 할수가 없어 테스트에 어려움이 있네요.. 위에 작성한부분이 많이 부족하지만. 문제가 될수 있는 부분 말씀해주시면 적용해 보도록 하겠습니다.
타이머 이벤트에서 바로 UDP send를 호출하는
타이머 이벤트에서 바로 UDP send를 호출하는 것보다는 세마포 시그널을 주고, 별도의 세마포를 기다리고 있는 쓰레드에서 UDP send를 하는 방식을 고려해 보세요.
같은 소켓을 쓰더라도 세마포로 대기하고 있음으로 별도의 lock은 필요하지 않겠네요.
댓글 달기