相关函数:
QWebSocketServer::QWebSocketServer(const QString &serverName, QWebSocketServer::SslMode secureMode, QObject *parent = nullptr)
/*使用给定的serverName构造一个新的QWebSocketServer。该服务器名称将在HTTP握手阶段被用来识别服务器。它可以为空,此时不会将服务器名称发送给客户端。
SslMode指示服务器是通过wss(SecureMode)还是ws(NonSecureMode)运行。QWebSocketServer::SecureMode服务器以安全模式运行(通过wss);QWebSocketServer::NonSecureMode服务器以非安全模式运行(通过ws)*/
void QWebSocketServer::setServerName(const QString &serverName)
//使用给定的serverName构造一个新的QWebSocketServer。该服务器名称将在HTTP握手阶段被用来识别服务器。它可以为空,此时不会将服务器名称发送给客户端。
bool QWebSocketServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
//监听指定的IP和端口。
[signal] void QWebSocketServer::newConnection()
//每当有新的客户端连接可用时,就会发出此信号。
QWebSocket *QWebSocketServer::nextPendingConnection()
//获取连接的客户端socket对象。
[signal] void QWebSocket::disconnected()
//每当有连接断开时,就会发出此信号。
QAbstractSocket::SocketError QWebSocket::error() const
//每当存在错误信息时,就会发出此信号。
[signal] void QWebSocket::textMessageReceived(const QString &message)
//每当接收到文本消息时,就会发出此信号。该消息包含收到的文本。常用来数据交互
[signal] void QWebSocket::binaryMessageReceived(const QByteArray &message)
//每当接收到二进制消息时,就会发出此信号。该消息包含接收到的字节。常用于文件发送
qint64 QWebSocket::sendTextMessage(const QString &message)
//发送文本数据
qint64 QWebSocket::sendBinaryMessage(const QByteArray &data)
//发送二进制数据
void QWebSocket::open(const QUrl &url)
//客户端开启连接请求,url格式:QString(ws://%1:%2).arg(ip).arg(port)
创建流程:
QWebsocket的使用方法和QTcpSocket特别像。
1、定义一个QWebSocketServer。
//使用给定的serverName构造一个新的QWebSocketServer。该服务器名称将在HTTP握手阶段被用来识别服务器。它可以为空,此时不会将服务器名称发送给客户端。
//SslMode指示服务器是通过wss(SecureMode)还是ws(NonSecureMode)运行。QWebSocketServer::SecureMode服务器以安全模式运行(通过wss);QWebSocketServer::NonSecureMode服务器以非安全模式运行(通过ws)
m_webSocketServer= new QWebSocketServer(“Server”,QWebSocketServer::NonSecureMode,this);
2、监听IP和端口
m_webSocketServer->listen(QHostAddress(m_ipEdit->text()),m_portEdit->text().toInt());
3、创建接收客户端的信号槽。
connect(m_webSocketServer,SIGNAL(newConnection()),this,SLOT(slotNewConnect()));
4、如果有客户端连接,则做处理,如获取socket连接,关联接收槽。
QWebSocket* socket = m_webSocketServer->nextPendingConnection();
connect(socket,&QWebSocket::disconnected,this,[=]()
{});
connect(socket,&QWebSocket::textMessageReceived,this,[=](QString text){});//每当接收到文本消息时,就会发出此信号。该消息包含收到的文本。常用来数据交互
connect(socket,&QWebSocket::binaryMessageReceived,this,[=](QByteArray array{});//每当接收到二进制消息时,就会发出此信号。该消息包含接收到的字节。常用于文件发送
发送文本:
socket->sendTextMessage(m_sendEdit->text());
发送二进制数据:
socket->sendBinaryMessage("IMGEND!");
发送图片:
QByteArray array;
QBuffer buffer(&array);
buffer.open(QIODevice::WriteOnly);
QPixmap pixmap(m_imgPath);
pixmap.save(&buffer,"png");
for (int i = 0; i < m_webSocketList.size() ;i++)
{
QWebSocket* socket = m_webSocketList.at(i);
QString head = "IMGSTART!|"+m_imgPath.split("/").last();
socket->sendBinaryMessage(head.toUtf8());
socket->sendBinaryMessage(array);
socket->sendBinaryMessage("IMGEND!");
}
发送文件:
m_blockSize = 64*1024;
QFileInfo fileinfo(m_filePath);
qint64 fileSize = fileinfo.size();
QString fileName = fileinfo.fileName();
QString head = QString("FILESTART!|%1#%2").arg(fileName).arg(fileSize);
QFile file(m_filePath);
file.open(QIODevice::ReadOnly);
qint64 sendSize = 0;
m_progressDialog->setRange(0,100);
m_progressDialog->setVisible(true);
qDebug() <<QStringLiteral("当前客户端:")<<m_webSocketList.size();
for (int i = 0; i < m_webSocketList.size() ;i++)
{
QWebSocket* socket = m_webSocketList.at(i);
socket->sendBinaryMessage(head.toUtf8());
QSslConfiguration config;
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::AnyProtocol);
socket->setSslConfiguration(config);
qint64 writesize = fileSize;
qint64 len = 0;
do{
QByteArray array = file.read(qMin(writesize,m_blockSize));
len = socket->sendBinaryMessage(array);
sendSize += len;
writesize -= len;
//由于发送太快,增加延时防止缓冲区来不及清理造成崩溃
if (sendSize%(100*1024*1024) == 0)
{
QEventLoop eventloop;
QTimer::singleShot(1000, &eventloop, SLOT(quit()));//3000表示3000ms,即3秒,可根据实际情况修改,其他的不用变
eventloop.exec();
}
m_progressDialog->setValue(sendSize/(fileSize/100));
qDebug() <<"sendsize:"<<sendSize;
}while(writesize>0);
if(sendSize == fileSize)//检验文件信息
{
qDebug() << QStringLiteral("文件发送完毕");
socket->sendBinaryMessage("FILEEND!");
file.close();
}
}
接收数据:```接收文本
connect(socket,&QWebSocket::textMessageReceived,this,[=](QString text)
{
m_recEdit->append(QStringLiteral("接收:")+text);
if (text == "Finish")
emit signalRecFinish();
qDebug()<<"------recv1"<<text;
});
``
接收数据:```接收二进制收据
connect(socket,&QWebSocket::binaryMessageReceived,this,[=](QByteArray array){
//就收图片头部
if (array.contains("IMGSTART!"))
{
m_rectype = IMGTYPE;
m_pixName = QString(array).split("|").last();
m_arr.clear();
}
//就收图片尾部
else if (array == "IMGEND!")
{
QPixmap pixmap;
pixmap.loadFromData(m_arr);
m_imgLab->setPixmap(pixmap.scaled(m_imgLab->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
m_pixName = m_pixName.remove("bak_");
pixmap.save(QApplication::applicationDirPath()+"/"+m_pixName);
m_arr.clear();
}
//接收文件头部
else if (array.contains("FILESTART!"))
{
m_rectype = FILETYPE;
QString str = array;
str = str.split("|").last();
QString fileName = str.section("#", 0, 0);
m_fileSize = str.section("#", 1, 1).toDouble();
m_recvSize = 0;
m_file.setFileName(fileName.remove("bak_"));
//打开文件
bool isOK = m_file.open(QIODevice::WriteOnly);
if(!isOK)
{
qDebug() << QStringLiteral("打开文件失败");
}
m_progressDialog->setRange(0,100);
m_progressDialog->setVisible(true);
}
//接收文件尾部
else if (array == "FILEEND!")
{
// if(m_recvSize == m_fileSize)
// {
qDebug() << QStringLiteral("实际")<< m_fileSize;
QMessageBox::information(this, QStringLiteral("完成"), QStringLiteral("接收文件成功"));
m_file.close();
// }
}
else
{
//接收图片的二进制数据
if (m_rectype == IMGTYPE)
{
m_arr.append(array);
}
//接收文件的二进制数据
else if (m_rectype == FILETYPE)
{
qint64 len = m_file.write(array);
m_recvSize += len;
qDebug() << QStringLiteral("接收") <<m_recvSize;
m_progressDialog->setValue(m_recvSize/(m_fileSize/100));
}
}
});