QT:Telnet客户端与服务器的创建

  • 客户端
  1. telnetClient类
#ifndef TELNETCLIENT_H
#define TELNETCLIENT_H

#include <QObject>
#include <QTcpSocket>

class TelnetClient : public QObject
{
    Q_OBJECT

public:
    explicit TelnetClient(QObject *parent = nullptr);
    ~TelnetClient();

    // 连接到指定的主机和端口
    bool connectToHost(const QString &hostname, quint16 port);

    // 发送数据到服务器
    void sendData(const QByteArray &data);

signals:
    // 连接成功
    void connected();

    // 连接断开
    void disconnected();

    // 收到数据
    void readyRead(const QByteArray &data);

    // 发生错误
    void errorOccurred(const QString &errorString);

private slots:
    // 处理服务器发送的数据
    void onReadyRead();

    // 处理连接错误
    void onError(QAbstractSocket::SocketError socketError);

private:
    QTcpSocket *tcpSocket;
};

#endif // TELNETCLIENT_H

#include "telnetclient.h"
#include <QDebug>

TelnetClient::TelnetClient(QObject *parent) :
    QObject(parent),
    tcpSocket(new QTcpSocket(this))
{
    connect(tcpSocket, &QTcpSocket::readyRead, this, &TelnetClient::onReadyRead);
    connect(tcpSocket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::errorOccurred),
            this, &TelnetClient::onError);
    connect(tcpSocket, &QTcpSocket::connected, [this]() {
        emit connected();
    });
    connect(tcpSocket, &QTcpSocket::disconnected, [this]() {
        emit disconnected();
    });
}

TelnetClient::~TelnetClient()
{
}

bool TelnetClient::connectToHost(const QString &hostname, quint16 port)
{
    tcpSocket->connectToHost(hostname, port);
    return tcpSocket->waitForConnected(3000); // 等待3秒以建立连接
}

void TelnetClient::sendData(const QByteArray &data)
{
    if (tcpSocket->state() == QAbstractSocket::ConnectedState) {
        tcpSocket->write(data);
        tcpSocket->flush();
    }
}

void TelnetClient::onReadyRead()
{
    QByteArray data = tcpSocket->readAll();
    emit readyRead(data);
}

void TelnetClient::onError(QAbstractSocket::SocketError socketError)
{
    Q_UNUSED(socketError);
    emit errorOccurred(tcpSocket->errorString());
}
  1. 应用

主程序

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
  • 窗口类
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

#include "telnetclient.h"

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void onConnectButtonClicked();
    void onTelnetReadyRead(const QByteArray &data);
    void onTelnetError(const QString &errorString);
    void onTelnetConnected();
    void onTelnetDisconnected();

private:
    Ui::MainWindow *ui;
    TelnetClient *telnetClient;

};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    connect(ui->connectButton, &QPushButton::clicked, this, &MainWindow::onConnectButtonClicked);
    connect(telnetClient, &TelnetClient::readyRead, this, &MainWindow::onTelnetReadyRead);
    connect(telnetClient, &TelnetClient::errorOccurred, this, &MainWindow::onTelnetError);
    connect(telnetClient, &TelnetClient::connected, this, &MainWindow::onTelnetConnected);
    connect(telnetClient, &TelnetClient::disconnected, this, &MainWindow::onTelnetDisconnected);
}

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

void MainWindow::onConnectButtonClicked()
{
    QString hostname = ui->hostLineEdit->text();
    quint16 port = ui->portLineEdit->text().toUInt();

    if (!telnetClient->connectToHost(hostname, port)) {
        ui->textEdit->append("Connection failed.");
    }
}

void MainWindow::onTelnetReadyRead(const QByteArray &data)
{
    ui->textEdit->append(data);
}

void MainWindow::onTelnetError(const QString &errorString)
{
    ui->textEdit->append("Error: " + errorString);
}

void MainWindow::onTelnetConnected()
{
    ui->textEdit->append("Connected to server.");
}

void MainWindow::onTelnetDisconnected()
{
    ui->textEdit->append("Disconnected from server.");
}

  • 服务器
  1. telnetServer类
#ifndef TELNETSERVER_H
#define TELNETSERVER_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>

class TelnetServer : public QObject
{
    Q_OBJECT

public:
    explicit TelnetServer(QObject *parent = nullptr);
    ~TelnetServer();

    // 启动服务器,监听指定端口
    bool start(quint16 port);

signals:
    // 当有新的客户端连接时
    void newConnection();

private slots:
    // 处理新客户端的连接
    void onNewConnection();

    // 处理客户端发送的数据
    void onReadyRead();

    // 处理客户端断开连接
    void onClientDisconnected();

private:
    QTcpServer *tcpServer;
    QList<QTcpSocket*> clients;
};

#endif // TELNETSERVER_H
#include "telnetserver.h"
#include <QDebug>

TelnetServer::TelnetServer(QObject *parent) :
    QObject(parent),
    tcpServer(new QTcpServer(this))
{
    connect(tcpServer, &QTcpServer::newConnection, this, &TelnetServer::onNewConnection);
}

TelnetServer::~TelnetServer()
{
    // 清理客户端连接
    for (QTcpSocket *client : clients) {
        client->disconnectFromHost();
        client->deleteLater();
    }
    clients.clear();
}

bool TelnetServer::start(quint16 port)
{
    if (!tcpServer->listen(QHostAddress::Any, port)) {
        qDebug() << "Server could not start!";
        return false;
    }

    qDebug() << "Server started on port" << port;
    return true;
}

void TelnetServer::onNewConnection()
{
    QTcpSocket *clientSocket = tcpServer->nextPendingConnection();
    clients.append(clientSocket);

    connect(clientSocket, &QTcpSocket::readyRead, this, &TelnetServer::onReadyRead);
    connect(clientSocket, &QTcpSocket::disconnected, this, &TelnetServer::onClientDisconnected);

    qDebug() << "New client connected!";
    emit newConnection();
}

void TelnetServer::onReadyRead()
{
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket*>(sender());
    if (!clientSocket)
        return;

    QByteArray data = clientSocket->readAll();
    qDebug() << "Received data:" << data;

    // Echo the data back to the client
    clientSocket->write(data);
}

void TelnetServer::onClientDisconnected()
{
    QTcpSocket *clientSocket = qobject_cast<QTcpSocket*>(sender());
    if (!clientSocket)
        return;

    clients.removeAll(clientSocket);
    clientSocket->deleteLater();

    qDebug() << "Client disconnected.";
}
  1. 应用
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "telnetserver.h"

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void onStartButtonClicked();
    void onNewConnection();

private:
    Ui::MainWindow *ui;
    TelnetServer *telnetServer;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    connect(ui->startButton, &QPushButton::clicked, this, &MainWindow::onStartButtonClicked);
    connect(telnetServer, &TelnetServer::newConnection, this, &MainWindow::onNewConnection);
}

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

void MainWindow::onStartButtonClicked()
{
    quint16 port = ui->portLineEdit->text().toUInt();
    if (telnetServer->start(port)) {
        ui->statusLabel->setText("Server started on port " + QString::number(port));
    } else {
        ui->statusLabel->setText("Failed to start server.");
    }
}

void MainWindow::onNewConnection()
{
    ui->statusLabel->setText("New client connected.");
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值