#qt
#qt
Вопрос:
Я создаю простую клиент-серверную программу, используя QTcpServer, QTcpSocket без использования thread, в fedora. Я хочу сделать свое приложение независимым от последовательности того, что запускается первым, клиент или сервер.Мое приложение работает нормально, когда я сначала запускаю сервер, но я не получаю никакого способа заставить клиента ждать, пока сервер не запущен, и подключиться с помощью serve в качестве запуска сервера. Я использовал waitForConnection(), но это не помогает. Пожалуйста, дайте несколько предложений.
TcpClient::TcpClient(QWidget *parent) : QMainWindow(parent),
ui(new Ui::TcpClient)
{
ui->setupUi(this);
tcpSocket= new QTcpSocket(this);
tcpSocket->connectToHost(QHostAddress::LocalHost,6178);
connect(tcpSocket, SIGNAL(connected()), this, SLOT(sendRequest()));
connect(tcpSocket, SIGNAL(disconnected()),this, SLOT(connectionClosedByServer()));
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(error()));
.
.
..
}
void TcpClient::error()
{
ui->lStatus->setText(tcpSocket->errorString());
closeConnection();
tcpSocket->connectToHost(QHostAddress::LocalHost,6178);
}
Ответ №1:
На клиенте используйте connectToHost()
. Прослушайте hostFound()
or connected()
для получения успеха и error()
для получения сбоя. При сбое просто попробуйте подключиться снова (возможно, через 1-10 секунд, используя QTimer::singleShot()
.)
Это позволит остальной части вашего приложения продолжать работать во время попыток подключения.
Комментарии:
1. Это работает. Если я напишу код подключения в слоте обработки ошибок, но безопасно ли это или хорошо? Мой код выглядит следующим образом <i> TcpClient::TcpClient(QWidget * parent) : QMainWindow(parent), ui (новый Ui:: TcpClient) { ui-> setupUi(this); TCPSocket= новый QTcpSocket(this); TCPSocket-> connectToHost(QHostAddress::LocalHost,6178);
2. подключитесь (TCPSocket, SIGNAL(connected()), this, СЛОТ (sendRequest())); подключитесь (TCPSocket, SIGNAL(disconnected()), this, СЛОТ(connectionClosedByServer())); подключитесь (TCPSocket, SIGNAL(ошибка(QAbstractSocket::SocketError)), this, СЛОТ(ошибка())); аннулируйте TcpClient::error() { пользовательский интерфейс-> lStatus->setText(TCPSocket->errorString()); CloseConnection(); TCPSocket-> connectToHost(QHostAddress::LocalHost,6178); }
3. @anjali: Ага. Пожалуйста, не публикуйте код в комментариях. Это почти невозможно прочитать. 🙂 … В любом случае, я бы написал слот с именем,
tryConnect()
который вызываетconnectToHost()
. Затем я бы сигнализировал об этом слоте, отложенном с помощью таймера, используя QTimer::singleShot(), когда выдается сообщение об ошибке () (если ошибка такова, что вы просто хотите повторить попытку’).4. Я отредактировал свой вопрос и написал свой код в этом, мой собственный слот error () похож на то, что вы говорите о TryConnect (), но я хочу знать, является ли это безопасной практикой или нет.
5. @anjali: Это достаточно безопасно, но вы должны проверить тип ошибки и посмотреть, является ли это исправимой ошибкой или нет (иногда вы хотите сообщить пользователю … и т.д.), И, как я уже сказал, подождите немного (0,1-5 секунд), прежде чем пытаться подключиться снова (чтобы избежать перегрузки процессора или сервера / сети).
Ответ №2:
Простой вызов connectToHost из слота, подключенного к error(), у меня не работает без опции подключения Qt::QueuedConnection. Смотрите сообщение Jonas Mauricio Gastal QTcpSocket повторно подключается после того, как соединение потеряно, оставаясь в состоянии ConnectingState. Извините за мой английский.