포춘 서버
네트워크 서비스용 서버를 만드는 방법을 설명합니다.
이 예제는 포춘 클라이언트 예제 또는 포춘 클라이언트 차단 예제와 함께 실행하기 위한 것입니다.
QTcpServer 을 사용하여 들어오는 TCP 연결을 수락하고 간단한 QDataStream 기반 데이터 전송 프로토콜을 사용하여 연결을 닫기 전에 연결 클라이언트에 포춘을 쓴 다음(포춘 클라이언트 예제에서) 포춘을 닫습니다.
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 을 설정합니다. 그런 다음 사용자가 포춘 클라이언트가 어느 포트에 연결해야 하는지 알 수 있도록 레이블에 선택된 포트 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 객체를 생성하여 QDataStream 의 생성자에 바이트 배열을 전달합니다. 그런 다음 QDataStream 의 프로토콜 버전을 QDataStream::Qt_5_10 로 명시적으로 설정하여 향후 버전의 Qt에서 클라이언트와 통신할 수 있도록 합니다( QDataStream::setVersion() 참조). 계속해서 무작위 포춘을 스트리밍합니다.
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의 이벤트 루프로 돌아갑니다. 그러면 소켓이 닫히고 QObject::deleteLater()가 소켓을 삭제합니다.
포춘 클라이언트 및 스레드 포춘 서버도참조하십시오 .
© 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.