GrabBag/VrNets/tcpServer/Src/VrTcpServer.cpp

282 lines
6.9 KiB
C++

#include "VrTcpServer.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QUuid>
#include <QDebug>
VrTcpServer::VrTcpServer(QObject *parent)
: IVrTcpServer(parent)
, m_server(new QTcpServer(this))
, m_port(0)
{
// 连接服务器信号
connect(m_server, &QTcpServer::newConnection, this, &VrTcpServer::onNewConnection);
connect(m_server, &QTcpServer::acceptError, this, [this](QAbstractSocket::SocketError error) {
emit serverError(m_server->errorString());
});
}
VrTcpServer::~VrTcpServer()
{
stopServer();
}
bool VrTcpServer::startServer(quint16 port)
{
if (m_server->isListening()) {
stopServer();
}
m_port = port;
bool result = m_server->listen(QHostAddress::Any, port);
if (result) {
emit serverStarted();
} else {
emit serverError(m_server->errorString());
}
return result;
}
void VrTcpServer::stopServer()
{
// 断开所有客户端连接
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
it.value()->disconnectFromHost();
}
m_clients.clear();
// 停止服务器监听
if (m_server->isListening()) {
m_server->close();
emit serverStopped();
}
m_port = 0;
}
bool VrTcpServer::isListening() const
{
return m_server->isListening();
}
quint16 VrTcpServer::serverPort() const
{
return m_port;
}
QStringList VrTcpServer::getClientIds() const
{
return m_clients.keys();
}
bool VrTcpServer::disconnectClient(const QString &clientId)
{
if (!m_clients.contains(clientId)) {
return false;
}
QTcpSocket *socket = m_clients[clientId];
socket->disconnectFromHost();
return true;
}
qint64 VrTcpServer::sendDataToClient(const QString &clientId, const QByteArray &data)
{
if (!m_clients.contains(clientId)) {
return -1;
}
QTcpSocket *socket = m_clients[clientId];
if (socket->state() != QAbstractSocket::ConnectedState) {
return -1;
}
return socket->write(data);
}
qint64 VrTcpServer::sendDataToClient(const QString &clientId, const char *data, qint64 size)
{
if (!m_clients.contains(clientId)) {
return -1;
}
QTcpSocket *socket = m_clients[clientId];
if (socket->state() != QAbstractSocket::ConnectedState) {
return -1;
}
return socket->write(data, size);
}
QHostAddress VrTcpServer::getClientAddress(const QString &clientId) const
{
if (!m_clients.contains(clientId)) {
return QHostAddress();
}
return m_clients[clientId]->peerAddress();
}
quint16 VrTcpServer::getClientPort(const QString &clientId) const
{
if (!m_clients.contains(clientId)) {
return 0;
}
return m_clients[clientId]->peerPort();
}
void VrTcpServer::onNewConnection()
{
while (m_server->hasPendingConnections()) {
QTcpSocket *socket = m_server->nextPendingConnection();
// 生成客户端ID
QString clientId = generateClientId(socket);
// 存储客户端连接
m_clients[clientId] = socket;
// 连接客户端信号
connect(socket, &QTcpSocket::disconnected, this, &VrTcpServer::onClientDisconnected);
connect(socket, &QTcpSocket::readyRead, this, &VrTcpServer::onClientReadyRead);
connect(socket, &QTcpSocket::bytesWritten, this, &VrTcpServer::onClientBytesWritten);
// 发送客户端连接信号
emit clientConnected(clientId);
}
}
void VrTcpServer::onClientDisconnected()
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
}
// 查找断开连接的客户端ID
QString clientId;
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
if (it.value() == socket) {
clientId = it.key();
break;
}
}
if (!clientId.isEmpty()) {
m_clients.remove(clientId);
emit clientDisconnected(clientId);
}
socket->deleteLater();
}
void VrTcpServer::onClientReadyRead()
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
}
// 查找客户端ID
QString clientId;
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
if (it.value() == socket) {
clientId = it.key();
break;
}
}
if (!clientId.isEmpty()) {
QByteArray data = socket->readAll();
if (!data.isEmpty()) {
emit dataReceived(clientId, data);
}
}
}
void VrTcpServer::onClientBytesWritten(qint64 bytes)
{
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
}
// 查找客户端ID
QString clientId;
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
if (it.value() == socket) {
clientId = it.key();
break;
}
}
if (!clientId.isEmpty()) {
emit dataSent(clientId, bytes);
}
}
void VrTcpServer::onServerError(QAbstractSocket::SocketError error)
{
Q_UNUSED(error)
QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
}
// 查找客户端ID
QString clientId;
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
if (it.value() == socket) {
clientId = it.key();
break;
}
}
if (!clientId.isEmpty()) {
emit serverError(QString("Client %1 error: %2").arg(clientId, socket->errorString()));
}
}
QString VrTcpServer::generateClientId(QTcpSocket *socket)
{
// 使用UUID生成唯一的客户端ID
return QUuid::createUuid().toString();
}
qint64 VrTcpServer::broadcastData(const QByteArray &data)
{
qint64 totalBytesWritten = 0;
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
QTcpSocket *socket = it.value();
if (socket->state() == QAbstractSocket::ConnectedState) {
qint64 bytesWritten = socket->write(data);
if (bytesWritten > 0) {
totalBytesWritten += bytesWritten;
}
}
}
return totalBytesWritten;
}
qint64 VrTcpServer::broadcastData(const char *data, qint64 size)
{
qint64 totalBytesWritten = 0;
for (auto it = m_clients.begin(); it != m_clients.end(); ++it) {
QTcpSocket *socket = it.value();
if (socket->state() == QAbstractSocket::ConnectedState) {
qint64 bytesWritten = socket->write(data, size);
if (bytesWritten > 0) {
totalBytesWritten += bytesWritten;
}
}
}
return totalBytesWritten;
}