C++ linux下的qt-tcp连接

C++ linux下的qt-tcp连接,c++,linux,qt,qtcpsocket,qtcpserver,C++,Linux,Qt,Qtcpsocket,Qtcpserver,我正在尝试在QT上创建一个客户机-服务器应用程序。我对算法没有问题。 QT很好。一切都很好,但只有在窗户下。 在Linux下运行应用程序时,客户端成功连接到服务器并成功写入 数据套接字->写入(myDataArray)=myDataArray.length(),但服务器不处理readyRead信号。 此问题仅在Linux下发生。有人知道发生了什么事吗? 我使用Ubuntu 14.04和Windows 7,qt版本5.3.2 客户端代码: #include "mainwindow.h" #inc

我正在尝试在QT上创建一个客户机-服务器应用程序。我对算法没有问题。 QT很好。一切都很好,但只有在窗户下。 在Linux下运行应用程序时,客户端成功连接到服务器并成功写入 数据套接字->写入(myDataArray)=myDataArray.length(),但服务器不处理readyRead信号。 此问题仅在Linux下发生。有人知道发生了什么事吗? 我使用Ubuntu 14.04和Windows 7,qt版本5.3.2


客户端代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

enum CONNECTION_TYPE{
    SSL_CONNECTION = 0,
    TCP_CONNECTION = 1
};

ClientMainWindow::ClientMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->socket = NULL;
    socketType = SSL_CONNECTION;
    msgI = 0;
}

ClientMainWindow::~ClientMainWindow()
{
    delete ui;
}

QAbstractSocket* ClientMainWindow::getSocket()
{
    bool wasError = false;
    QAbstractSocket *socket;
    if (SSL_CONNECTION == this->socketType)
    {
        QString keyFileName = "baseEnicsKey.key";
        QString certificateFileName =  "baseEnicsCertificate.csr";
        QSsl::KeyAlgorithm algorithm = QSsl::Rsa;
        QSsl::EncodingFormat encodingFormat = QSsl::Pem;
        QByteArray passPhrase = "pass0";

        QSslSocket *sslSocket = new QSslSocket(this);


        QByteArray  key;
        QFile  fileKey(keyFileName);
        if(fileKey.open(QIODevice ::ReadOnly))
        {
           key = fileKey.readAll();
           fileKey.close();
        }
        else
        {
            wasError = true;
            qDebug() << fileKey.errorString();
        }

        QSslKey sslKey(key, algorithm, encodingFormat, QSsl::PrivateKey, passPhrase);
        sslSocket->setPrivateKey(sslKey);


        QByteArray  certificate;
        QFile  fileCertificate(certificateFileName);
        if(fileCertificate.open(QIODevice ::ReadOnly))
        {
           certificate = fileCertificate.readAll();
           fileCertificate.close();
        }else
        {
           qDebug() << fileCertificate.errorString()
                    << fileCertificate.fileName();
           wasError = true;
        }
        if(!wasError){
            QSslCertificate sslCertificate;
            sslCertificate = QSslCertificate(certificate);

            sslSocket->addCaCertificate(sslCertificate);
            sslSocket->setLocalCertificate(sslCertificate);

            QList<QSslCertificate> sslCertificates;
            sslCertificates.append(sslCertificate);
            sslSocket->setDefaultCaCertificates(sslCertificates);

            sslSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
            sslSocket->setProtocol(QSsl::SslV3);
            socket = sslSocket;         
        }
        else{
            socket = NULL;
        }
    }
    else
    {
        socket = new QTcpSocket();   
    }
    return socket;
}

void ClientMainWindow::readyReadSlot()
{
    QDataStream in(this->socket);
    in.setVersion(QDataStream::Qt_5_0);
    quint32 blockSize = 0;
    qDebug() << "Client::readData";
    if (this->socket->bytesAvailable() >= (int)sizeof(quint32))
    {
        in >> blockSize;
        if (this->socket->bytesAvailable() >= blockSize)
        {
            QByteArray b;
            in >> b;
            qDebug() << "from client :"<< b;
        }
        else
        {
            qDebug() << "error : this->tcpSocket->bytesAvailable() < blockSize";
        }
    }
    else
    {
        qDebug() << "error : this->tcpSocket->bytesAvailable() < (int)sizeof(quint32)\n";
    }

}


void ClientMainWindow::newDataForWriteSlot(QByteArray b)
{
    b.append("--");
    b.append(QString::number(msgI));
    msgI++;
    qDebug() << "newDataForWriteSlot: " << b;
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_0);
    out << (quint32)0;
    out << b;
    out.device()->seek(0);
    out << (quint32)(block.size() - sizeof(quint32));
    qDebug() << "block length" << block.length();
    qDebug() << "write length"<< this->socket->write(block);
    this->socket->flush();
}

void ClientMainWindow::sslErrorSlot(QList<QSslError> error)
{
    qDebug() << "sslErrorSlot: " << error;
    ((QSslSocket*)this->socket)->ignoreSslErrors();
}

void ClientMainWindow::socketErrorSlot(QAbstractSocket::SocketError error)
{
    qDebug() << "socketErrorSlot: " << error;
}

void ClientMainWindow::isEncryptionReadySlot()
{
    qDebug() << "isEncryptionReadySlot";
}

void ClientMainWindow::isConnectedSlot()
{
    qDebug() << "isConnectedSlot";
}

void ClientMainWindow::encryptedBytesWrittenSlot(qint64 x)
{
    qDebug() << "encryptedBytesWrittenSlot: " << x;
}

void ClientMainWindow::connectToServer()
{
    delete this->socket;
    this->socket = getSocket();

    if (SSL_CONNECTION == this->socketType)
    {

        connect(((QSslSocket*)this->socket), SIGNAL(sslErrors(QList<QSslError>)),
                this, SLOT(sslErrorSlot(QList<QSslError>))
        );
        connect(((QSslSocket*)this->socket), SIGNAL(encryptedBytesWritten(qint64)),
                this, SLOT(encryptedBytesWrittenSlot(qint64))
        );
    }
    connect(this->socket, SIGNAL(connected()),
            this, SLOT(isConnectedSlot()));
    connect(this->socket, SIGNAL(readyRead()),
            this, SLOT(readyReadSlot())
    );
    connect(this, SIGNAL(newDataForWriteSignal(QByteArray)),
            this, SLOT(newDataForWriteSlot(QByteArray))
    );
    connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(socketErrorSlot(QAbstractSocket::SocketError))
    );
    QString hostName = "127.0.0.1";
    int port = 9600;
    if (SSL_CONNECTION == this->socketType)
    {
        ((QSslSocket*)this->socket)->connectToHostEncrypted(
                    hostName,
                    port,
                    QSslSocket::ReadWrite,
                    QSslSocket::IPv4Protocol);
    }
    else
    {
        this->socket->connectToHost(
                    hostName, 
                    port,
                    QSslSocket::ReadWrite,
                    QSslSocket::IPv4Protocol);    
    }
    if(!this->socket->waitForConnected())
    {
        qDebug() << "connection time out";    
    }
    this->newDataForWriteSlot("Hi I'm Client. It's my first connection.");
}

void ClientMainWindow::on_pushButton_clicked()
{
    this->socketType = SSL_CONNECTION;
    this->connectToServer();
}

void ClientMainWindow::on_pushButton_2_clicked()
{
    this->socketType = TCP_CONNECTION;
    this->connectToServer();
}

void ClientMainWindow::on_pushButton_3_clicked()
{
    this->newDataForWriteSlot("hi, i'm client!");
}
#包括“mainwindow.h”
#包括“ui_main window.h”
枚举连接类型{
SSL_连接=0,
TCP_连接=1
};
ClientMainWindow::ClientMainWindow(QWidget*父项):
QMainWindow(父级),
用户界面(新用户界面::主窗口)
{
用户界面->设置用户界面(此);
此->套接字=空;
socketType=SSL\u连接;
msgI=0;
}
ClientMainWindow::~ClientMainWindow()
{
删除用户界面;
}
QAbstractSocket*ClientMainWindow::getSocket()
{
boolwaserror=false;
QAbstractSocket*socket;
如果(SSL_连接==此->套接字类型)
{
QString keyFileName=“baseEnicsKey.key”;
QString certificateFileName=“baseEnicCertificate.csr”;
QSsl::KeyAlgorithm算法=QSsl::Rsa;
QSsl::EncodingFormat EncodingFormat=QSsl::Pem;
QByteArray密码短语=“pass0”;
QSslSocket*sslSocket=新QSslSocket(此);
QByteArray键;
QFile文件密钥(keyFileName);
if(fileKey.open(QIODevice::ReadOnly))
{
key=fileKey.readAll();
fileKey.close();
}
其他的
{
wasError=真;
qDebug()setPrivateKey(sslKey);
QByteArray证书;
QFile文件证书(certificateFileName);
if(fileCertificate.open(QIODevice::ReadOnly))
{
certificate=fileCertificate.readAll();
fileCertificate.close();
}否则
{
qDebug()setLocalCertificate(sslCertificate);
QList SSL证书;
SSLC证书。附加(SSLC证书);
sslSocket->setDefaultCaCertificates(sslCertificates);
sslSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
sslSocket->setProtocol(QSsl::SslV3);
插座=sslSocket;
}
否则{
socket=NULL;
}
}
其他的
{
套接字=新的QTcpSocket();
}
返回插座;
}
void ClientMainWindow::readyReadSlot()
{
QDataStream(此->套接字);
in.setVersion(QDataStream::Qt_5_0);
块大小=0;
qDebug()套接字->字节可用()>=(int)sizeof(quint32))
{
在>>块大小中;
if(this->socket->bytesavable()>=blockSize)
{
QByteArray b;
在>>b;
qDebug()连接到HostEncrypted(
主机名,
港口,
QSslSocket::读写,
QSslSocket::IPV4协议);
}
其他的
{
此->套接字->连接到主机(
主机名,
港口,
QSslSocket::读写,
QSslSocket::IPV4协议);
}
如果(!this->socket->waitForConnected())
{
qDebug()newDataForWriteSlot(“嗨,我是客户,这是我的第一次连接。”);
}
void clientmain窗口::在按钮上单击()
{
此->socketType=SSL\u连接;
这->连接到服务器();
}
void clientmain窗口::在按钮上单击(2)
{
此->socketType=TCP\U连接;
这->连接到服务器();
}
void clientmain窗口::在按钮上单击3
{
这->newDataForWriteSlot(“嗨,我是客户!”);
}

服务器代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

enum CONNECTION_TYPE{
    SSL_CONNECTION = 0,
    TCP_CONNECTION = 1
};


ServerMainWindow::ServerMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->server = new QTcpServer();
    connect(this->server, SIGNAL(newConnection()),
            this, SLOT(incomingConnectionSlot()));
    connect(this->server, SIGNAL(acceptError(QAbstractSocket::SocketError)),
            this, SLOT(serverErrorSlot(QAbstractSocket::SocketError))
            );
    QHostAddress adress;
    adress.setAddress("127.0.0.1");
    int port = 9600;

    this->socketType = SSL_CONNECTION;
    this->socket = NULL;
    if (!this->server->listen(adress, port))
    {
        qDebug() << "Server could not start";
    }
    msgI = 0 ;
}

ServerMainWindow::~ServerMainWindow()
{
    delete ui;
}

void ServerMainWindow::incomingConnectionSlot()
{

    disconnect(this->socket, SIGNAL(readyRead()),
            this, SLOT(readyReadSlot()));
    disconnect(this, SIGNAL(newDataForWriteSignal(QByteArray)),
            this, SLOT(newDataForWriteSlot(QByteArray))
            );
    disconnect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(socketErrorSlot(QAbstractSocket::SocketError))
            );
    if (SSL_CONNECTION == socketType)
    {
        disconnect(((QSslSocket*)this->socket), SIGNAL(peerVerifyError(QSslError)),
                this, SLOT(peerVerrefyErrorSlot(QSslError))
                );
        disconnect(((QSslSocket*)this->socket), SIGNAL(encrypted()),
                this, SLOT(isEncryptionReadySlot())
                );
        disconnect(((QSslSocket*)this->socket), SIGNAL(encryptedBytesWritten(qint64)),
                   this, SLOT(encryptedDataWriteSlot(qint64)));
    }

    delete this->socket;
    this->socket = this->getSocket();

    this->incomingConnection(
                this->server->nextPendingConnection()->socketDescriptor());

    connect(this->socket, SIGNAL(readyRead()),
            this, SLOT(readyReadSlot())
            );

    connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(socketErrorSlot(QAbstractSocket::SocketError))
            );
    if (SSL_CONNECTION == socketType)
    {
        connect(((QSslSocket*)this->socket), SIGNAL(encrypted()),
            this, SLOT(isEncryptionReadySlot())
            );
        connect(((QSslSocket*)this->socket), SIGNAL(peerVerifyError(QSslError)),
                this, SLOT(peerVerrefyErrorSlot(QSslError))
                );
        connect(((QSslSocket*)this->socket), SIGNAL(encryptedBytesWritten(qint64)),
                   this, SLOT(encryptedDataWriteSlot(qint64)));
        ((QSslSocket*)this->socket)->startServerEncryption();
    }
    qDebug() << "is socket open" << this->socket->isOpen();
    this->newDataForWriteSlot("Hi I'm Server! It's my first connection!");

}

void ServerMainWindow::incomingConnection(qintptr socketDescriptor)
{
    qDebug() << "incomingConnection" << socketDescriptor;
    this->socket->setSocketDescriptor(socketDescriptor);
}

QAbstractSocket* ServerMainWindow::getSocket()
{
    bool wasError = false;
    QAbstractSocket *socket;
    if (SSL_CONNECTION == this->socketType)
    {
        QString keyFileName = "baseEnicsKey.key";
        QString certificateFileName =  "baseEnicsCertificate.csr";
        QSsl::KeyAlgorithm algorithm = QSsl::Rsa;
        QSsl::EncodingFormat encodingFormat = QSsl::Pem;
        QByteArray passPhrase = "pass0";

        QSslSocket *sslSocket = new QSslSocket(this);


        QByteArray  key;
        QFile  fileKey(keyFileName);
        if(fileKey.open(QIODevice ::ReadOnly))
        {
           key = fileKey.readAll();
           fileKey.close();
        }
        else
        {
            wasError = true;
            qDebug() << fileKey.errorString();
        }

        QSslKey sslKey(key, algorithm, encodingFormat, QSsl::PrivateKey, passPhrase);
        sslSocket->setPrivateKey(sslKey);


        QByteArray  certificate;
        QFile  fileCertificate(certificateFileName);
        if(fileCertificate.open(QIODevice ::ReadOnly))
        {
           certificate = fileCertificate.readAll();
           fileCertificate.close();
        }else
        {
           qDebug() << fileCertificate.errorString()
                    << fileCertificate.fileName();
           wasError = true;
        }
        if(!wasError){
            QSslCertificate sslCertificate;
            sslCertificate = QSslCertificate(certificate);

            sslSocket->addCaCertificate(sslCertificate);
            sslSocket->setLocalCertificate(sslCertificate);

            QList<QSslCertificate> sslCertificates;
            sslCertificates.append(sslCertificate);
            sslSocket->setDefaultCaCertificates(sslCertificates);

            sslSocket->setPeerVerifyMode(QSslSocket::QueryPeer);
            sslSocket->setProtocol(QSsl::SslV3);
            socket = sslSocket;
        }
        else{
            socket = NULL;
        }
    }
    else
    {
        socket = new QTcpSocket();        
    }
    return socket;
}

void ServerMainWindow::readyReadSlot()
{
    QDataStream in(this->socket);
    in.setVersion(QDataStream::Qt_5_0);
    quint32 blockSize = 0;
    qDebug() << "Server::readData";
    if (this->socket->bytesAvailable() >= sizeof(quint32))
    {
        in >> blockSize;
        qDebug() << "this->socket->bytesAvailable" << this->socket->bytesAvailable();
        if (this->socket->bytesAvailable() >= blockSize)
        {
            QByteArray b;
            in >> b;
            qDebug() << "from client: " << b;
        }
        else
        {
            qDebug() << "error : this->tcpSocket->bytesAvailable() < blockSize";
            QByteArray b;
            in >> b;
            qDebug() << b;
        }
    }
    else
    {
        qDebug() << "error : this->tcpSocket->bytesAvailable() < (int)sizeof(quint32)";
    }

}


void ServerMainWindow::newDataForWriteSlot(QByteArray b)
{
    b.append("--");
    b.append(QString::number(msgI));
    msgI++;
    qDebug() << "newDataForWriteSlot: "<< b;

    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);

    out.setVersion(QDataStream::Qt_5_0);
    out << (quint32)0;
    out << b;
    out.device()->seek(0);
    out << (quint32)(block.size() - sizeof(quint32));
    qDebug() << "block length" << block.length();
    qDebug() << "write length"<< this->socket->write(block);
    this->socket->flush();
}

void ServerMainWindow::peerVerrefyErrorSlot(QSslError error)
{
    qDebug() << "peerVerrefyErrorSlot: " << error;
}

void ServerMainWindow::socketErrorSlot(QAbstractSocket::SocketError error)
{
    qDebug() << "socketErrorSlot: " << error;
}

void ServerMainWindow::isEncryptionReadySlot()
{
    qDebug() << "isEncryptionReadySlot";
}


void ServerMainWindow::serverErrorSlot(QAbstractSocket::SocketError error)
{
    qDebug() << "serverErrorSlot: " << error;
}


void ServerMainWindow::on_checkBox_clicked()
{
    if(ui->checkBox->isChecked())
    {
        this->socketType = SSL_CONNECTION;    
    }
    else
    {
        this->socketType = TCP_CONNECTION; 
    }
}

void ServerMainWindow::encryptedDataWriteSlot(qint64 x)
{
    qDebug() << "encryptedDataWrite" << x;
}

void ServerMainWindow::on_writeButton_clicked()
{
    this->newDataForWriteSlot("I'm server!");
}
#包括“mainwindow.h”
#包括“ui_main window.h”
枚举连接类型{
SSL_连接=0,
TCP_连接=1
};
ServerMainWindow::ServerMainWindow(QWidget*父项):
QMainWindow(父级),
用户界面(新用户界面::主窗口)
{
用户界面->设置用户界面(此);
此->服务器=新的QTcpServer();
连接(此->服务器,信号(newConnection()),
此插槽(incomingConnectionSlot());
连接(此->服务器,信号(acceptError(QAbstractSocket::SocketError)),
此插槽(serverErrorSlot(QAbstractSocket::SocketError))
);
QHostAddress地址;
地址设置地址(“127.0.0.1”);
int端口=9600;
此->socketType=SSL\u连接;
此->套接字=空;
如果(!this->server->listen(地址、端口))
{
qDebug()插槽,信号(readyRead()),
这个,SLOT(readyReadSlot());
断开(此,信号(newDataForWriteSignal(QByteArray)),
此插槽(newDataForWriteSlot(QByteArray))
);
断开连接(此->套接字,信号(错误(QAbstractSocket::SocketError)),
这个插槽(socketErrorSlot(QAbstractSocket::SocketError))
);
如果(SSL_连接==socketType)
{
断开(((QSslSocket*)此->套接字)、信号(peerVerifyError(QSslError)),
此插槽(PeerRefyerrorSlot(QSslError))
);
断开((QSslSocket*)此->套接字)、信号(加密的()),
此插槽(isEncryptionReadySlot())
);
断开((QSslSocket*)此->插座)、信号(EncryptedBytesWrite(qint64)),
这个插槽(encryptedDataWriteSlot(qint64));
}
删除此->套接字;
this->socket=this->getSocket();
此->输入连接(
此->服务器->下一个EndingConnection()->socketDescriptor());
连接(此->套接字,信号(readyRead()),
此插槽(readyReadSlot())
);
连接(此->套接字,信号(错误(QAbstractSocket::SocketError)),
这个插槽(socketErrorSlot(QAbstractSocket::SocketError))
);
如果(SSL_连接==socketType)
{
连接((QSslSocket*)此->套接字)、信号(加密的()),
此插槽(isEncryptionReadySlot()