- 客户端
- 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());
}
- 应用
主程序
#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.");
}
- 服务器
- 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.";
}
- 应用
#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.");
}