본문 바로가기
개발

Qt 네트워크 프로그래밍 팁

by 솜씨제이 2011. 6. 11.
Qt로 네트워크 프로그래밍을 할 때 주의하거나 참고할 만한 팁들을 정리해보았다. Qt 4.7.0 버전 대상이라 다른 버전에서는 조금 다를 수도 있다.
  1. Http를 위해 사용하는 QNetworkAccessManager에서 Persistent Cookie를 지원하지 않는다.
    QNetworkCookieJar를 상속해서 별도로 구현해야 한다.
    아래 툴 소스에서 구현 예제를 찾을 수 있다.(PersistentCookieJar)

    qt/tools/qml/qmlruntime.cpp
  2. 바로가기 파일(.lnk)가 심볼릭 링크로 처리된다.
    QFileInfo::isDir(), QFileInfo::exists() 등의 함수가  바로가기 파일이 아니라 대상 파일의 속성이 나오니 주의해야 한다.
  3. Signal, slot 연결 시 멀티스레드 처리

    • 각 QObject는 연관된 스레드가 있고 생성될 때 생성 스레드로 정해진다.
    • QObject에서 signal, slot 연결을 할 때 서로 다른 스레드에서는 Qt::DirectConnection을 쓰면 스레드 동기화 문제가 발생할 수 있기 때문에 Qt::QueuedConnection을 써야 한다.
    • Signal, slot 연결에서 Qt::AutoConnection을 사용하면 연관 스레드가 같은 경우는 Qt::DirectConnection, 다른 경우는 Qt::QueuedConnection으로 동작한다.
    • Signal 연결을 하려면 QThread 인스턴스는 생성자에서 moveToThread(this)를 해주는 것이 좋다.
    • 스레드에서 사용하는 Qt 클래스 변수는 스레드 내부에서 생성하거나 moveToThread(thread)를 해주는 것이 좋다.
    • 일부 Qt 클래스는 사용하려는 스레드에서 생성하지 않으면 제대로 동작하지 않는 경우가 있다.(QTcpSocket)
    • Qt::QueuedConnection으로 연결된 메시지는 event loop에서 처리된다.
    • Event loop에서 아직 처리되지 않은 signal이 남아 있는 경우 QThread 인스턴스를 재사용하면 다시 생성된 스레드에서 처리된다. 남아 있는 Signal을 처리하지 않으려면 QThread 인스턴스를 다시 생성해서 스레드를 생성해야 한다.
    • Signal을 다른 signal에 연결할 수 있는데 Qt::QueuedConnection에서는 동작하지 않는다.
  4. QNetworkAccessManager는 비동기 방식으로 동작한다. 동기화해서 사용하려면 아래처럼 처리하면 된다.

    QNetworkReply* reply; QEventLoop loop; connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); loop.exec(QEventLoop::ExcludeUserInputEvents);
  5. QNetworkReply를 중단하려면 abort를 호출하고 delete한다.
  6. 작업 중에 signal을 처리하고 싶다면 QEventLoop::processEvents()를 사용한다.

    QEventLoop loop; while (...) { loop.processEvents(QEventLoop::AllEvents, 100); ... }
  7. QDirIterator는 마지막 아이템까지 진행하지 않으면 핸들 리소스릭이 발생하고 디렉토리에 lock이 걸린다. 상속해서 소멸자에서 마지막 아이템까지 진행하도록 처리하는 것이 좋다.

    MyDirIterator::~MyDirIterator() { while (hasNext()) next(); }
  8. 프로세스간 통신(IPC)은 QSharedMemory와 QSystemSemaphore을 사용한다. Linux에서는 QtDBus 모듈을 사용할 수 있다.
  9. Mac에서는 qcore_mac_p.h에 있는 QCFType, QCFString을 사용할 수 있는데 Mac용 SDK에 소스가 포함되어 있지 않아 다른 OS의 SDK에서 복사하거나 별도로 Qt 라이브러리를 다운로드해야 한다.
  10. Mac 파일 시스템은 UTF-8 decomposed form을 사용한다. 일반적인 유니코드(composed form)으로 변환하려면 QFile::decodeName()을 사용하고 반대는 QFile::encodeName()을 사용한다.

댓글