Fortune 서버
네트워크 서비스를 위한 서버를 생성하는 방법을 보여줍니다.
이 예제는 Fortune 클라이언트 예제나 Blocking Fortune 클라이언트 예제와 함께 실행하도록 설계되었습니다.

이 예제는 ` QTcpServer `를 사용하여 들어오는 TCP 연결을 수락하고, 간단한 ` QDataStream ` 기반 데이터 전송 프로토콜을 통해 연결된 클라이언트( Fortune Client 예제)에 포춘 메시지를 전송한 후 연결을 종료합니다.
class Server : public QDialog
{
Q_OBJECT
public:
explicit Server(QWidget *parent = nullptr);
private slots:
void sendFortune();
private:
void initServer();
QLabel *statusLabel = nullptr;
QTcpServer *tcpServer = nullptr;
QList<QString> fortunes;
};서버는 들어오는 연결을 처리하기 위한 슬롯이 하나뿐인 간단한 클래스를 사용하여 구현됩니다.
tcpServer = new QTcpServer(this);
if (!tcpServer->listen()) {
QMessageBox::critical(this, tr("Fortune Server"),
tr("Unable to start the server: %1.")
.arg(tcpServer->errorString()));
close();
return;
}
QString ipAddress;
const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
for (const QHostAddress &entry : ipAddressesList) {
if (entry != QHostAddress::LocalHost && entry.toIPv4Address()) {
ipAddress = entry.toString();
break;
}
}
// if we did not find one, use IPv4 localhost
if (ipAddress.isEmpty())
ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
statusLabel->setText(tr("The server is running on\n\nIP: %1\nport: %2\n\n"
"Run the Fortune Client example now.")
.arg(ipAddress).arg(tcpServer->serverPort()));생성자에서 Server 객체는 QTcpServer::listen()를 호출하여 임의의 포트에서 모든 주소를 수신 대기하는 QTcpServer 를 설정합니다. 그런 다음 사용자가 Fortune Client가 연결해야 할 포트를 알 수 있도록, 선택된 포트 QTcpServer 를 레이블에 표시합니다.
fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
<< tr("You've got to think about tomorrow.")
<< tr("You will be surprised by a loud noise.")
<< tr("You will feel hungry again in another hour.")
<< tr("You might have mail.")
<< tr("You cannot kill time without injuring eternity.")
<< tr("Computers are not intelligent. They only think they are.");서버는 연결된 클라이언트에게 전송할 수 있는 무작위 포춘 목록을 생성합니다.
connect(tcpServer, &QTcpServer::newConnection, this, &Server::sendFortune);클라이언트가 서버에 연결하면, QTcpServer 는 QTcpServer::newConnection()를 호출합니다. 이에 따라 sendFortune() 슬롯이 호출됩니다:
void Server::sendFortune()
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_6_5);
out << fortunes[QRandomGenerator::global()->bounded(fortunes.size())];이 슬롯의 목적은 포춘 문구 목록에서 무작위 문구를 하나 선택하고, ` QDataStream`를 사용하여 이를 ` QByteArray `로 인코딩한 다음, 연결된 소켓에 쓰는 것입니다. 이는 ` QTcpSocket`를 사용하여 바이너리 데이터를 전송하는 일반적인 방법입니다. 먼저 ` QByteArray `와 ` QDataStream ` 객체를 생성하고, `bytearray`를 ` QDataStream`의 생성자에 전달합니다. 그런 다음, 향후 버전의 Qt 클라이언트와도 통신할 수 있도록 QDataStream 의 프로토콜 버전을 QDataStream::Qt_5_10 로 명시적으로 설정합니다( QDataStream::setVersion() 참조). 이어서 임의의 ‘fortune’ 메시지를 스트리밍합니다.
QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
connect(clientConnection, &QAbstractSocket::disconnected,
clientConnection, &QObject::deleteLater);그런 다음 QTcpServer::nextPendingConnection()를 호출하면, 연결의 서버 측을 나타내는 QTcpSocket 가 반환됩니다. QTcpSocket::disconnected()를 QObject::deleteLater()에 연결함으로써, 연결이 끊어진 후 소켓이 삭제되도록 보장합니다.
clientConnection->write(block);
clientConnection->disconnectFromHost();
}인코딩된 운세는 QTcpSocket::write()을 사용하여 작성되며, 마지막으로 QTcpSocket::disconnectFromHost()을 호출합니다. 이 함수는 QTcpSocket 가 네트워크에 운세 작성을 완료한 후 연결을 닫습니다. QTcpSocket 는 비동기적으로 작동하므로, 이 함수가 반환된 후에 데이터가 작성되고 제어권은 Qt Network의 이벤트 루프로 돌아갑니다. 그러면 소켓이 닫히게 되며, 이에 따라 QObject::deleteLater()가 해당 소켓을 삭제하게 됩니다.
Fortune 클라이언트 및 스레드 기반 Fortune 서버도 참조하십시오 .
© 2026 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.