2013-11-20 91 views
2

程序有效,但客户端无法连接到服务器。 (我运行2个程序的例子:客户端和服务器)。我找不到我的错误在哪里。为什么客户端不连接到服务器? Qt

我写了下面的代码。你会看到我想要做的,如果你看看主要功能。

//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(); } 

帮我请!

+0

我编辑了你的帖子,在'server.cpp'的末尾有一个可能是拼写错误的括号。 – user2485710

+0

没有必要实例化一个单独的QTcpServer作为Server isa QTcpServer。即不需要tcpServer = new QTcpServer(this);并且你有类似tcpServer-> listen的地方做'this-> listen'而不是...如果修复它,我会发布正确的答案 –

回答

1

这可能是因为main.cpp中的while循环,它会阻止客户端的事件循环,并且会在输入'exit'后立即返回到事件循环。我的意思是这行:

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

这可怎么避免:main.cpp中必须达到return a.exec();行启动事件循环(我不包括一些丑陋processEvent解决方案的时候了)。

将命令发送到cmd并不会阻止事件循环,我用类,我看到这里的某个地方在计算器:

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(); 

AAAND看哪,ConsoleReader类,头:main.cpp中的

例如

#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

非常感谢! – ExiD

1

在您的主函数中,您在堆栈中创建客户端和服务器,当它们超出switch语句的范围时,它们将被删除。

你需要动态地分配在堆上的对象: -

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

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

虽然客户端将继续,因为它创建后while循环,服务器将被创建,启动监听,然后被删除,以及QTcpSocket,因为它有服务器作为其父。

+0

谢谢!但它仍然不发送消息:( – ExiD

+0

所以,我需要做一个更多的循环为服务器? – ExiD

+0

你是什么意思'一个更多的循环为服务器'? – TheDarkKnight

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"; 
} 

我想问题可能是其试图做的东西有不同的对象,而不是“本”对象。

+0

我认为这是没有问题的〜Server()在程序中没有调用 – ExiD

+0

Sever启动完全,但sti我不会收到消息。 – ExiD

相关问题