본문 바로가기

카테고리 없음

Qt를 활용한 네트워크 실전 프로그래밍 (1)

목적

Qt Framework에서 제공하는 QTcpSocket, QThread Class를 활용하고 Half-sync, half-async 동기화 패턴을 적용한 이더넷 네트워크 상에서의 동기식 쓰기, 비동기식 읽기 요청을 지원하는 TCP Client Application을 개발하는 절차와 방법을 설명한다.

 

개요

Qt는 네트워크 프로그래밍을 위한 풍부한 Socket API를 지원하고 단일 thread에서 signal/slot 방식으로 socket 이벤트를 처리할 수 있게 함으로써 보다 쉬운 네트워크 개발 환경을 제공한다고 한다. 실제로 Qt Creator에서 제공하는 샘플 코드를 통해 간단한 TCP/IP 프로토콜 기반의 server, client를 쉽게 만들어 볼 수 있다.

하지만 실제 업무에서 Qt를 활용하여 TCP/IP 프로토콜을 사용하는 진단 application 개발을 진행하면서 나는 며칠간 별다른 진척이 없을 정도로 여러가지 어려움에 부딪히게 되었다.

 

처음에는 socket으로 패킷을 write해도 수신되는 응답 패킷의 data를 도무지 read해서 아예 출력할 수 조차 없었다. 

우선 개발하려는 application은 server에 진단 요청을 보내는 client application으로 tcp socket을 사용하여 동기식으로 요청과 응답을 받아야 하는데 이와 동시에 server에서 보내는 비동기적인 메시지도 처리해야 한다는  것이었다. 하지만 이런 요구 사항을 만족하는 sample code를 찾을 수는 없었다.

그래서 나름대로 생각을 해서 동기식 통신 처리를 담당하는 thread를 추가해 보았는데 이번에는 tcp scoket 이벤트 signal 발생 시 socket 객체를 포함한 thread가 아닌 다른 thread에 해당 이벤트에 대한 slot이 연결되어 있다면 해당 slot은 호출되지 않는다는 제약사항이 있어 응답 packet의 data를 처리할 수가 없는 것이었다.

 

Qt Forum Q&A를 통해 많은 Qt개발자들이 비슷한 문제로 고민을 했다는 것을 알 수가 있었고 다음 Qt guide 문서를 읽어보면서 내가 Qt 개발을 위한 기본 지식이 부족했었음을 알 수 있었다.

Threads Events QObjects/ko - Qt Wiki

 

Threads Events QObjects/ko - Qt Wiki

En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh STILL WORKING ON 원본 영문버젼의 내용이 업데이트가 되었는지 확인해 이 문서도 함께 갱신되어야 합니다(번역기준으로 원본의 문서리비젼:

wiki.qt.io

Qt의 Event loop와 QObject의 thread affinity에 대한 이해가 충분하지 않은 상태로 개발을 진행하다보니 문제가 발생할 수 밖에 없었고 해당 내용을 완전히는 아니지만 어느정도 이해한 다음 어플리케이션 구조를 GUI 이벤트를 처리하는 main dialog thread, 동기식 진단 세션을 처리하는 진단 세션 thread 그리고 비동기식 TCP/IP socket 이벤트를 처리하는 socket adaptor thread로 나누고 thread 사이에 signal/slot 방식으로 통신하도록 함으로써 목표로 했던 진단 application 개발을 완료하게 되었다.

 

* 다음 내용을 포함하여 구체적인 구현 내용에 대해 서술할 예정입니다.

1. Event loop (exec())

2. Signal-slot (connect())

3. QThread, Thread affinity (moveToThread())

4. Socket descriptor (다른 Thread에 Socket descriptor를 전달)

5. 동기식 TcpSocket 이벤트 처리(waitForWritten, waitForReadyRead)

6. 데이터 동기화 (Mutex, WaitCondition)

7. 동기화 패턴 (Active object, Half-sync half-async)

8. Serialize (Endian, Byte alignment)