Почему клиент не подключается к серверу? Qt

Программа работает, но клиент не может подключиться к серверу. (Я запускаю 2 примера программы: клиент и сервер). Я не могу найти, где моя ошибка.

Я написал коды ниже. Вы увидите, что я хочу сделать, если вы посмотрите на основную функцию.

//main.cpp
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//выбор клиента или сервера
cout << "1.Client\n2.Server\n";
switch (_getch())
{
case 49:
{
cout<<"client init\n";
Client* cli = new Client("localhost",1922);

string line;
while(line!="exit") {
cout << "Message : ";
cin >> line;
cli->SendData(QString(line.c_str()));
}
break;
}
case 50:
{
cout<<"server init\n";
Server* srv = new Server(0, 1922);
break;
}
}

return a.exec();
}

//server.h
class Server : public QTcpServer {
Q_OBJECT public : Server(QObject *parent = 0, quint16 port = 1922);
virtual ~Server();

private
slots:
void acceptConnection();
void startRead();
void disconnected();

private:
QTcpServer *tcpServer;
QTcpSocket *client;
};

//server.cpp
Server::Server(QObject *parent, quint16 port) : QTcpServer(parent) {
//tcpServer = new QTcpServer(this);
connect(this, SIGNAL(newConnection()), this, SLOT(acceptConnection()));

if (!this->listen(QHostAddress::Any, port))
std::cout << "unable to start server\n"<< this->errorString().toUtf8().constData() << endl;
else
std::cout << "server started\n";
}

Server::~Server() {
//delete client;
close();
}

void Server::acceptConnection() {
std::cout << "new connection!\n";
client = nextPendingConnection();

connect(client, SIGNAL(readyRead()), this, SLOT(startRead()));
connect(client, SIGNAL(disconnected()), this, SLOT(disconnected()));

qDebug() << "New client from:" << client->peerAddress().toString();
}

void Server::startRead() {
client = (QTcpSocket *)sender();
while (client->canReadLine()) {
QString line = QString::fromUtf8(client->readLine()).trimmed();
qDebug() << "Client :" << line;

client->write(QString("Server : I've taken your message (:\n").toUtf8());
}

}

void Server::disconnected() {

qDebug() << "Client disconnected:" << client->peerAddress().toString();

client->write(QString("Server : I wish you didn't leave ):\n").toUtf8());

}

//} <-- EDIT: THIS IS PROBABLY AN EXTRA

//***************************************************************
//client.h
class Client : public QObject {
Q_OBJECT public : Client(const QString &add, int port, QObject *obj = 0);
void SendData(QString data);
virtual ~Client();
int status();
QString err;
private
slots:
void ReadData();
void slotConnected();
void slotError(QAbstractSocket::SocketError);

private:
QTcpSocket *socket;

};

//client.cpp
Client::Client(const QString &add, int port, QObject *obj) : QObject(obj) {
//create socket
socket = new QTcpSocket(this);
//connect
socket ->connectToHost(add, port);

connect(socket, SIGNAL(readyRead()), SLOT(ReadData()));
connect(socket, SIGNAL(connected()), SLOT(slotConnected()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
SLOT(slotError(QAbstractSocket::SocketError)));

}

Client::~Client() {
socket->close();
delete socket;
}

void Client::SendData(QString data) {
if (!data.isEmpty()) {
QByteArray arrBlock;
QDataStream out(&arrBlock, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_1);
out << quint16(0) << QTime::currentTime() << data;
out.device()->seek(0);
out << quint16(arrBlock.size() - sizeof(quint16));

socket->write(arrBlock);
socket->flush();
}
}

void Client::ReadData() {
QDataStream in(socket);
in.setVersion(QDataStream::Qt_5_1);
while (socket->canReadLine()) {

QString line = QString::fromUtf8(socket->readLine()).trimmed();
qDebug() << line;
}
}

void Client::slotConnected() {
socket->write(QString("Client : Server connection has been made (: \n")
.toUtf8());
}

void Client::slotError(QAbstractSocket::SocketError err) {
QString strError =
"Error: " + (err == QAbstractSocket::HostNotFoundError
? "The host was not found.": err == QAbstractSocket::RemoteHostClosedError
? "The remote host is closed.": err == QAbstractSocket::ConnectionRefusedError
? "The connection was refused.": QString(socket->errorString()));
std::cout << strError.toUtf8().constData() << endl;
}

int Client::status() { return socket->state(); }

помогите мне пожалуйста!

2

Решение

Вероятно, это из-за цикла while в main.cpp, он блокирует цикл событий клиента и вернется в цикл событий сразу после того, как будет напечатан ‘exit’. Я имею в виду эти строки:

while (line != "exit") {
cout << "Message : ";
cin >> line;
cli.SendData(QString(line.c_str()));
}

Как этого можно избежать: main.cpp ДОЛЖЕН достигать return a.exec(); строка, чтобы начать цикл событий (я исключаю некоторые уродливые ProcessEvent решения сразу).

Чтобы отправить команды в cmd и НЕ блокировать цикл обработки событий, я использовал класс, который я видел где-то здесь на stackoverflow:

пример main.cpp:

QCoreApplication a(argc, argv);
qDebug()<<"Press 'q' to quit";

QTcpServer server;

qDebug()<<"Server is started -"<<server.isListening();

// Console reader to filter console input
ConsoleReader reader;
QObject::connect(&reader,SIGNAL(shutdown()),&a,SLOT(quit()));

return a.exec();

ааа, вот ConsoleReader класс, заголовок:

#ifndef CONSOLEREADER_H
#define CONSOLEREADER_H

#pragma once

#include <QObject>
#include <QSocketNotifier>

class ConsoleReader : public QObject
{
Q_OBJECT
public:
explicit ConsoleReader(QObject *parent = 0);
~ConsoleReader();
signals:
void shutdown();
public slots:
void text();
private:
QSocketNotifier* notifier;
};

#endif // CONSOLEREADER_H

источник:

#include "consolereader.h"#include <QTextStream>
#include <QDebug>
#include <unistd.h> //Provides STDIN_FILENO

ConsoleReader::ConsoleReader(QObject *parent) :
QObject(parent)
{
notifier = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read);
connect(notifier, SIGNAL(activated(int)), this, SLOT(text()));
}

void ConsoleReader::text()
{
QTextStream qin(stdin);
QString line = qin.readLine();
if (line==QString("q")){
qDebug()<<"Shutting down the server..";
emit shutdown();
}
else qDebug()<<"Unknown command: "<<line;

}

ConsoleReader::~ConsoleReader(){
delete notifier;
}
1

Другие решения

В вашей основной функции вы создаете в стеке и клиента, и сервер, которые затем удаляются, когда они выходят за рамки оператора switch.

Вам нужно динамически распределять объекты в куче: —

Server* pServer = new Server(0, 1922);

Client* pClient = new Client("localhost" 1922);

Хотя клиент останется, из-за цикла while после его создания сервер будет создан, начните прослушивание, затем удалите его вместе с QTcpSocket, так как он имеет сервер в качестве родителя.

1

Как я упоминал в своем комментарии, нет необходимости создавать отдельный QTCpServer, так как сервер является QTcpServer. Итак, где у вас есть:

Server::Server(QObject *parent, quint16 port) : QTcpServer(parent) {
tcpServer = new QTcpServer(this);
connect(this, SIGNAL(newConnection()), this, SLOT(acceptConnection()));

if (!tcpServer->listen(QHostAddress::Any, port))
std::cout << "unable to start server\n"<< tcpServer->errorString().toUtf8().constData() << endl;
else
std::cout << "server started\n";
}

Изменить на:

Server::Server(QObject *parent, quint16 port) : QTcpServer(parent) {

connect(this, SIGNAL(newConnection()), this, SLOT(acceptConnection()));

if (!this->listen(QHostAddress::Any, port))
std::cout << "unable to start server\n"<< this->errorString().toUtf8().constData() << endl;
else
std::cout << "server started\n";
}

Я думаю, что проблема может заключаться в том, что он пытается делать что-то с другим объектом, а не с объектом this.

1
По вопросам рекламы [email protected]