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