QTcpSocket, дождитесь сервера

#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. Извините за мой английский.