QObject 를 상속 받아 UDP 구현시 다중 sendto 문제

wogns041의 이미지

안녕하세요. 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를 하는 방식을 고려해 보세요.

같은 소켓을 쓰더라도 세마포로 대기하고 있음으로 별도의 lock은 필요하지 않겠네요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.