使用 Qt 提供的类进行套接字通信比使用标准 C API 进行网络通信要简单(因为在内部进行了封装)原始的 TCP 通信流程 Qt 中的套接字通信流程如下:
1 服务器端 1.1 通信流程 创建套接字服务器 QTcpServer 对象 通过 QTcpServer 对象设置监听,即:QTcpServer::listen() 基于 QTcpServer::newConnection() 信号检测是否有新的客户端连接 如果有新的客户端连接调用 QTcpSocket *QTcpServer::nextPendingConnection() 得到通信的套接字对象 使用通信的套接字对象 QTcpSocket 和客户端进行通信 1.2 代码片段 服务器端的窗口界面如下图所示:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_startServer_clicked();
void on_sendMsg_clicked();
private:
Ui::MainWindow *ui;
QTcpServer* m_server;
QTcpSocket* m_tcp;
};
源文件
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("TCP - 服务器");
m_server = new QTcpServer(this);
connect(m_server, &QTcpServer::newConnection, this, [=]()
{
m_tcp = m_server->nextPendingConnection();
ui->record->append("成功和客户端建立了新的连接...");
m_status->setPixmap(QPixmap(":/connect.png").scaled(20, 20));
connect(m_tcp, &QTcpSocket::readyRead, this, [=]()
{
QString recvMsg = m_tcp->readAll();
ui->record->append("客户端Say: " + recvMsg);
});
connect(m_tcp, &QTcpSocket::disconnected, this, [=]()
{
ui->record->append("客户端已经断开了连接...");
m_tcp->deleteLater();
m_status->setPixmap(QPixmap(":/disconnect.png").scaled(20, 20));
});
});
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_startServer_clicked()
{
unsigned short port = ui->port->text().toInt();
m_server->listen(QHostAddress::Any, port);
ui->startServer->setEnabled(false);
}
void MainWindow::on_sendMsg_clicked()
{
QString sendMsg = ui->msg->toPlainText();
m_tcp->write(sendMsg.toUtf8());
ui->record->append("服务器Say: " + sendMsg);
ui->msg->clear();
}
2 客户端 2.1 通信流程 创建通信的套接字类 QTcpSocket 对象 使用服务器端绑定的 IP 和端口连接服务器 QAbstractSocket::connectToHost() 使用 QTcpSocket 对象和服务器进行通信 2.2 代码片段 客户端的窗口界面如下图所示:
头文件
C++
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_connectServer_clicked();
void on_sendMsg_clicked();
void on_disconnect_clicked();
private:
Ui::MainWindow *ui;
QTcpSocket* m_tcp;
};
源文件
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("TCP - 客户端");
m_tcp = new QTcpSocket(this);
connect(m_tcp, &QTcpSocket::readyRead, [=]()
{
QByteArray recvMsg = m_tcp->readAll();
ui->record->append("服务器Say: " + recvMsg);
});
connect(m_tcp, &QTcpSocket::connected, this, [=]()
{
ui->record->append("恭喜, 连接服务器成功!!!");
m_status->setPixmap(QPixmap(":/connect.png").scaled(20, 20));
});
connect(m_tcp, &QTcpSocket::disconnected, this, [=]()
{
ui->record->append("服务器已经断开了连接, ...");
ui->connectServer->setEnabled(true);
ui->disconnect->setEnabled(false);
});
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_connectServer_clicked()
{
QString ip = ui->ip->text();
unsigned short port = ui->port->text().toInt();
m_tcp->connectToHost(QHostAddress(ip), port);
ui->connectServer->setEnabled(false);
ui->disconnect->setEnabled(true);
}
void MainWindow::on_sendMsg_clicked()
{
QString sendMsg = ui->msg->toPlainText();
m_tcp->write(sendMsg.toUtf8());
ui->record->append("客户端Say: " + sendMsg);
ui->msg->clear();
}
void MainWindow::on_disconnect_clicked()
{
m_tcp->close();
ui->connectServer->setEnabled(true);
ui->disconnect->setEnabled(false);
}
参考: https://subingwen.cn/qt/socket-tcp/#2-2-%E4%BF%A1%E5%8F%B7
|