Qt를 이용한 네트워크 프로그래밍

Qt Network 모듈은 TCP/IP 클라이언트와 서버를 작성할 수 있는 클래스를 제공합니다. 낮은 수준의 네트워크 개념을 나타내는 QTcpSocket, QTcpServer, QUdpSocket 와 같은 저수준 클래스와 일반적인 프로토콜을 사용하여 네트워크 작업을 수행하는 QNetworkRequest, QNetworkReply, QNetworkAccessManager 와 같은 고수준 클래스를 제공합니다.

Qt의 네트워크 프로그래밍을 위한 클래스

Qt Network C++ Classes 페이지에 Qt Network 의 C++ 클래스 목록이 포함되어 있습니다.

HTTP를 위한 고수준 네트워크 연산

네트워크 액세스 API는 일반적인 네트워크 연산을 수행하기 위한 클래스 모음입니다. 이 API는 사용되는 특정 작업 및 프로토콜(예: HTTP를 통한 데이터 가져오기 및 게시)에 대한 추상화 계층을 제공하며 일반 또는 상위 수준의 개념에 대한 클래스, 함수 및 신호만 노출합니다.

네트워크 요청은 QNetworkRequest 클래스로 표시되며, 이 클래스는 헤더 정보 및 사용된 암호화 등 요청과 관련된 정보를 위한 일반 컨테이너 역할도 합니다. 요청 객체가 구성될 때 지정된 URL에 따라 요청에 사용되는 프로토콜이 결정됩니다. 현재 업로드 및 다운로드에는 HTTP 및 로컬 파일 URL이 지원됩니다.

네트워크 작업의 조정은 QNetworkAccessManager 클래스에 의해 수행됩니다. 요청이 생성되면 이 클래스는 요청을 발송하고 진행 상황을 보고하는 신호를 전송하는 데 사용됩니다. 또한 관리자는 클라이언트의 데이터, 인증 요청 및 프록시 사용을 저장하기 위해 cookies 사용을 조정합니다.

네트워크 요청에 대한 응답은 QNetworkReply 클래스로 표시되며, 요청이 발송되면 QNetworkAccessManager 에 의해 생성됩니다. QNetworkReply 에서 제공하는 시그널을 사용하여 각 응답을 개별적으로 모니터링하거나, 개발자가 대신 관리자의 시그널을 사용하여 응답에 대한 참조를 삭제할 수 있습니다. QNetworkReplyQIODevice 의 서브클래스이므로 회신은 동기 또는 비동기, 즉 차단 또는 비차단 작업으로 처리할 수 있습니다.

각 애플리케이션이나 라이브러리는 하나 이상의 QNetworkAccessManager 인스턴스를 생성하여 네트워크 통신을 처리할 수 있습니다.

QTcpSocket 및 QTcpServer와 함께 TCP 사용

TCP(전송 제어 프로토콜)는 HTTP 및 FTP를 포함한 대부분의 인터넷 프로토콜에서 데이터 전송을 위해 사용하는 저수준 네트워크 프로토콜입니다. 안정적이고 스트림 지향적이며 연결 지향적인 전송 프로토콜입니다. 특히 데이터의 지속적인 전송에 적합합니다.

A TCP Stream

QTcpSocket 클래스는 TCP용 인터페이스를 제공합니다. QTcpSocket 을 사용하여 POP3, SMTP, NNTP와 같은 표준 네트워크 프로토콜과 사용자 정의 프로토콜을 구현할 수 있습니다.

데이터 전송을 시작하려면 먼저 원격 호스트 및 포트에 대한 TCP 연결이 설정되어야 합니다. 연결이 설정되면 QTcpSocket::peerAddress() 및 QTcpSocket::peerPort()를 통해 피어의 IP 주소와 포트를 확인할 수 있습니다. 언제든지 피어가 연결을 닫을 수 있으며, 그러면 데이터 전송이 즉시 중지됩니다.

QTcpSocket 는 비동기적으로 작동하며 QNetworkAccessManager 와 마찬가지로 상태 변경 및 오류를 보고하는 신호를 보냅니다. 이벤트 루프에 의존하여 들어오는 데이터를 감지하고 나가는 데이터를 자동으로 플러시합니다. QTcpSocket::write ()를 사용하여 소켓에 데이터를 쓰고 QTcpSocket::read()를 사용하여 데이터를 읽을 수 있습니다. QTcpSocket 는 읽기용과 쓰기용의 두 가지 독립적인 데이터 스트림을 나타냅니다.

QTcpSocketQIODevice 을 상속하므로 QTextStreamQDataStream 과 함께 사용할 수 있습니다. QTcpSocket 에서 읽을 때는 미리 QTcpSocket::bytesAvailable()을 호출하여 충분한 데이터를 사용할 수 있는지 확인해야 합니다.

서버 애플리케이션에서 들어오는 TCP 연결을 처리해야 하는 경우(예: 서버 애플리케이션에서) QTcpServer 클래스를 사용합니다. QTcpServer::listen ()를 호출하여 서버를 설정하고, 접속하는 모든 클라이언트에 대해 한 번씩 전송되는 QTcpServer::newConnection() 신호에 연결합니다. 슬롯에서 QTcpServer::nextPendingConnection()를 호출하여 연결을 수락하고 반환된 QTcpSocket 을 사용하여 클라이언트와 통신합니다.

대부분의 함수는 비동기적으로 작동하지만 QTcpSocket 을 동기적으로(즉, 차단) 사용할 수도 있습니다. 블로킹 동작을 얻으려면 QTcpSocket 의 waitFor...() 함수를 호출하면 신호가 전송될 때까지 호출 스레드가 일시 중단됩니다. 예를 들어, 비차단 QTcpSocket::connectToHost() 함수를 호출한 후 QTcpSocket::waitForConnected() 함수를 호출하여 connected() 신호가 전송될 때까지 스레드를 차단합니다.

동기식 소켓은 종종 제어 흐름이 더 단순한 코드로 이어집니다. waitFor...() 접근 방식의 가장 큰 단점은 waitFor...() 함수가 차단되는 동안 이벤트가 처리되지 않는다는 것입니다. GUI 스레드에서 사용하면 애플리케이션의 사용자 인터페이스가 멈출 수 있습니다. 따라서 GUI 스레드가 아닌 스레드에서만 동기식 소켓을 사용하는 것이 좋습니다. 동기식으로 사용하는 경우 QTcpSocket 이벤트 루프가 필요하지 않습니다.

포춘 클라이언트포춘 서버 예제에서는 QTcpSocketQTcpServer 을 사용하여 TCP 클라이언트-서버 애플리케이션을 작성하는 방법을 보여줍니다. 이벤트 루프를 사용하지 않고 별도의 스레드에서 동기식 QTcpSocket 을 사용하는 방법에 대한 예는 블로킹 포춘 클라이언트, 활성 클라이언트당 하나의 스레드가 있는 멀티스레드 TCP 서버의 예는 스레드 포춘 서버 를 참조하세요.

QUdpSocket과 함께 UDP 사용

UDP(사용자 데이터그램 프로토콜)는 가볍고 안정적이지 않은 데이터그램 중심의 비연결 프로토콜입니다. 안정성이 중요하지 않은 경우에 사용할 수 있습니다. 예를 들어, 시간을 보고하는 서버는 UDP를 선택할 수 있습니다. 시간이 포함된 데이터그램이 손실되면 클라이언트는 간단히 다른 요청을 하면 됩니다.

UDP Packets

QUdpSocket 클래스를 사용하면 UDP 데이터그램을 주고받을 수 있습니다. QAbstractSocket 을 상속하므로 QTcpSocket 의 인터페이스 대부분을 공유합니다. 가장 큰 차이점은 QUdpSocket 은 데이터를 연속적인 데이터 스트림이 아닌 데이터그램으로 전송한다는 것입니다. 간단히 말해, 데이터그램은 전송되는 데이터 외에 데이터그램의 발신자와 수신자의 IP 주소와 포트가 포함된 제한된 크기(일반적으로 512바이트보다 작음)의 데이터 패킷입니다.

QUdpSocket IPv4 브로드캐스팅을 지원합니다. 브로드캐스팅은 네트워크에서 하드 디스크 여유 공간이 가장 많은 호스트를 찾는 등 네트워크 검색 프로토콜을 구현하는 데 자주 사용됩니다. 한 호스트가 데이터그램을 네트워크에 브로드캐스트하면 다른 모든 호스트가 이를 수신합니다. 그러면 요청을 받은 각 호스트는 발신자에게 현재 사용 가능한 디스크 공간의 양을 회신으로 보냅니다. 발신자는 모든 호스트로부터 회신을 받을 때까지 기다린 다음 데이터를 저장할 여유 공간이 가장 많은 서버를 선택할 수 있습니다. 데이터그램을 브로드캐스트하려면 특수 주소 QHostAddress::Broadcast (255.255.255.255) 또는 로컬 네트워크의 브로드캐스트 주소로 전송하면 됩니다.

QUdpSocket::bind()는 TCP 서버의 QTcpServer::listen()와 마찬가지로 들어오는 데이터그램을 받을 수 있도록 소켓을 준비합니다. 하나 이상의 데이터그램이 도착할 때마다 QUdpSocketreadyRead() 신호를 보냅니다. QUdpSocket::readDatagram ()를 호출하여 데이터그램을 읽습니다.

브로드캐스트 발신자와 브로드캐스트 수신자 예제는 Qt를 사용하여 UDP 발신자와 UDP 수신자를 작성하는 방법을 보여줍니다.

QUdpSocket 멀티캐스팅도 지원합니다. 멀티캐스트 발신자멀티캐스트 수신자 예제는 쓰기 UDP 멀티캐스트 클라이언트를 사용하는 방법을 보여줍니다.

QHostInfo를 사용하여 호스트 이름 확인하기

네트워크 연결을 설정하기 전에 QTcpSocketQUdpSocket 은 이름 조회를 수행하여 연결하려는 호스트 이름을 IP 주소로 변환합니다. 이 작업은 일반적으로 DNS(도메인 이름 서비스) 프로토콜을 사용하여 수행됩니다.

QHostInfo 는 이러한 조회를 직접 수행할 수 있는 정적 함수를 제공합니다. 호스트 이름, QObject 포인터 및 슬롯 서명과 함께 QHostInfo::lookupHost()를 호출하면 QHostInfo 이 이름 조회를 수행하고 결과가 준비되면 지정된 슬롯을 호출합니다. 실제 조회는 별도의 스레드에서 수행되며, 운영 체제의 이름 조회를 수행하는 자체 메서드를 사용합니다.

QHostInfo 또한 호스트 이름을 인수로 받아 결과를 반환하는 QHostInfo::fromName()라는 정적 함수를 제공합니다. 이 경우 이름 조회는 호출자와 동일한 스레드에서 수행됩니다. 이 오버로드는 비구글 애플리케이션이나 별도의 비구글 스레드에서 이름 조회를 수행할 때 유용합니다. (GUI 스레드에서 이 함수를 호출하면 함수가 조회를 수행하는 동안 사용자 인터페이스가 멈출 수 있습니다.)

네트워크 프록시 지원

프록시는 로컬과 원격 연결 사이의 네트워크 트래픽을 지시하거나 필터링하는 프록시를 통해 Qt와의 네트워크 통신을 수행할 수 있습니다.

개별 프록시는 QNetworkProxy 클래스로 표현되며, 이는 프록시에 대한 연결을 설명하고 구성하는 데 사용됩니다. 다양한 수준의 네트워크 통신에서 작동하는 프록시 유형이 지원되며, SOCKS 5는 낮은 수준의 네트워크 트래픽 프록시를 허용하고 HTTP 및 FTP 프록시는 프로토콜 수준에서 작동합니다. 자세한 내용은 QNetworkProxy::ProxyType 을 참조하세요.

프록시는 소켓 단위로 또는 애플리케이션의 모든 네트워크 통신에 대해 활성화할 수 있습니다. 새로 열린 소켓은 연결되기 전에 QAbstractSocket::setProxy() 함수를 호출하여 프록시를 사용하도록 설정할 수 있습니다. 애플리케이션 전체 프록시는 QNetworkProxy::setApplicationProxy() 함수를 사용하여 이후의 모든 소켓 연결에 대해 활성화할 수 있습니다.

프록시 팩토리는 프록시 사용에 대한 정책을 만드는 데 사용됩니다. QNetworkProxyFactory 는 특정 프록시 유형에 대한 쿼리를 기반으로 프록시를 제공합니다. 쿼리 자체는 QNetworkProxyQuery 객체로 인코딩되어 프록시의 목적(TCP, UDP, TCP 서버, URL 요청), 로컬 포트, 원격 호스트 및 포트, 사용 중인 프로토콜(HTTP, FTP 등) 등의 주요 기준에 따라 프록시를 선택할 수 있습니다.

QNetworkProxyFactory::proxyForQuery()는 팩토리를 직접 쿼리하는 데 사용됩니다. 프록시에 대한 애플리케이션 전체 정책은 QNetworkProxyFactory::setApplicationProxyFactory()에 팩토리를 전달하여 구현할 수 있으며, 사용자 정의 프록시 정책은 QNetworkProxyFactory 을 서브클래싱하여 생성할 수 있습니다(자세한 내용은 클래스 설명서를 참조하세요).

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.