2. TCP服务器基础监听
任务目标
实现一个基于QTcpServer的TCP服务器,监听指定端口(默认8888),接受客户端连接,并将收到的消息原样回显给客户端。通过QT自带的客户端工具或telnet即可验证功能。
环境依赖
Qt 5.12+(含Network模块),在.pro文件中添加:
QT += core network
关键完整代码
// tcp_echo_server.h
#ifndef TCP_ECHO_SERVER_H
#define TCP_ECHO_SERVER_H
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
class TcpEchoServer : public QObject
{
Q_OBJECT
public:
explicit TcpEchoServer(quint16 port, QObject *parent = nullptr);
private slots:
void onNewConnection();
void onReadyRead();
void onClientDisconnected();
private:
QTcpServer *m_server;
};
#endif // TCP_ECHO_SERVER_H
// tcp_echo_server.cpp
#include "tcp_echo_server.h"
#include <QDebug>
TcpEchoServer::TcpEchoServer(quint16 port, QObject *parent)
: QObject(parent), m_server(new QTcpServer(this))
{
if (!m_server->listen(QHostAddress::Any, port)) {
qDebug() << "监听失败:" << m_server->errorString();
return;
}
qDebug() << "服务器已启动,监听端口:" << port;
connect(m_server, &QTcpServer::newConnection,
this, &TcpEchoServer::onNewConnection);
}
void TcpEchoServer::onNewConnection()
{
while (m_server->hasPendingConnections()) {
QTcpSocket *client = m_server->nextPendingConnection();
qDebug() << "新客户端连接:" << client->peerAddress().toString()
<< ":" << client->peerPort();
connect(client, &QTcpSocket::readyRead,
this, &TcpEchoServer::onReadyRead);
connect(client, &QTcpSocket::disconnected,
this, &TcpEchoServer::onClientDisconnected);
}
}
void TcpEchoServer::onReadyRead()
{
QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
if (!client) return;
QByteArray data = client->readAll();
qDebug() << "收到消息:" << QString::fromUtf8(data);
client->write(data); // 回显
}
void TcpEchoServer::onClientDisconnected()
{
QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
if (!client) return;
qDebug() << "客户端断开:" << client->peerAddress().toString();
client->deleteLater();
}
// main.cpp
#include <QCoreApplication>
#include "tcp_echo_server.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
quint16 port = 8888;
if (argc > 1) {
port = QString(argv[1]).toUShort();
}
TcpEchoServer server(port);
return a.exec();
}
运行与验证
编译运行:
qmake
make
./tcp_echo_server 8888
验证步骤:
- 启动服务器,控制台输出“服务器已启动,监听端口: 8888”;
- 打开终端,使用telnet连接:
telnet 127.0.0.1 8888; - 在telnet中输入任意文本(如“hello”),按回车;
- 服务器控制台打印“收到消息: hello”,同时telnet窗口立即显示“hello”回显;
- 输入多行不同内容,每次均能收到相同回显,说明回显功能正常;
- 关闭telnet,服务器控制台打印“客户端断开: 127.0.0.1”,服务器不崩溃,可继续接受新连接。
通过条件:客户端发送的每条消息都能被原样返回,且服务器日志中依次出现连接、收消息、断开的记录,即判定实现正确。
常见问题
- 端口被占用:换用其他端口(如8889)启动,或先释放占用端口的进程。
- telnet不可用:Windows需在“启用或关闭Windows功能”中勾选Telnet客户端;Linux使用
apt install telnet安装。 - 中文乱码:本示例使用UTF-8收发,若客户端发送GBK编码,可在
onReadyRead中改用QString::fromLocal8Bit(data)接收。