Qt中的TCP服务端和客户端互发消息

170 阅读3分钟

Qt中的TCP服务端和客户端互发消息

作者:hackett

微信公众号:加班猿

废话不多说,上演示效果

由于我们用到socketLamda表达式,所以工程.pro文件需要添加对应的库

image-20201111195456610

为了方便,main.cpp中让程序显示两个Widget窗口,程序运行起来就可以测试

 ServerWidget w; w.show(); ClientWidget w2; w2.show();

一、服务端

服务端的UI界面布局:

2个PushButton(send,close)

2个textEdit(发送内容,接收内容)

image-20201111201341091

新建一个监听套接字,监听端口号为9999的IP,等待连接,有连接过来提示成功连接同时服务端读就绪

  //监听套接字,指定父对象,让其自动回收空间 tcpServer = new QTcpServer(this); ​ tcpServer->listen(QHostAddress::Any, 9999); ​ setWindowTitle("服务器: 9999"); ​ //newConnection代表有新的连接 connect(tcpServer, &QTcpServer::newConnection,         [=]()         {             //取出建立好连接的套接字             tcpSocket = tcpServer->nextPendingConnection(); ​             //获取对方的IP和端口             QString ip = tcpSocket->peerAddress().toString();             quint16 port = tcpSocket->peerPort();             QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);             ui->textEditRead->setText(temp); ​             //readyRead代表读就绪             connect(tcpSocket, &QTcpSocket::readyRead,                     [=]()                     {                         //从通信套接字中取出内容                         QByteArray array = tcpSocket->readAll();                         ui->textEditRead->append(array);                     }                    );         }        );

二、客户端

客户端的UI界面布局:

3个PushButton(connect,send,close)

2个lineEdit(端口号,IP)

2个textEdit(发送内容,接收内容)

image-20201111200014145

客户端连接按钮主动与服务端建立连接

 void ClientWidget::on_buttonConnect_clicked() {     //获取服务器ip和端口     QString ip = ui->lineEditIP->text();     qint16 port = ui->lineEditPort->text().toInt(); ​     //主动和服务器建立连接     tcpSocket->connectToHost(QHostAddress(ip), port); ​ }

连接成功后会触发connected,提示"成功和服务器建立好连接"同时客户端读就绪

 //分配空间,指定父对象 tcpSocket = new QTcpSocket(this); ​ setWindowTitle("客户端"); ​ ​ connect(tcpSocket, &QTcpSocket::connected,         [=]()         {             ui->textEditRead->setText("成功和服务器建立好连接");         }        ); ​ connect(tcpSocket, &QTcpSocket::readyRead,         [=]()         {             //获取对方发送的内容             QByteArray array = tcpSocket->readAll();             //追加到编辑区中             ui->textEditRead->append(array);         } ​        );

源码

main.cpp

 #include "serverwidget.h" #include <QApplication> #include "clientwidget.h"int main(int argc, char *argv[]) {     QApplication a(argc, argv);     ServerWidget w;     w.show(); ​     ClientWidget w2;     w2.show(); ​     return a.exec(); }

serverwidget.cpp

 #include "serverwidget.h" #include "ui_serverwidget.h" #include <QDebug> ​ ServerWidget::ServerWidget(QWidget *parent) :     QWidget(parent),     ui(new Ui::ServerWidget) {     ui->setupUi(this); ​     tcpServer = NULL;     tcpSocket = NULL; ​     //监听套接字,指定父对象,让其自动回收空间     tcpServer = new QTcpServer(this); ​     tcpServer->listen(QHostAddress::Any, 9999); ​     setWindowTitle("服务器: 9999"); ​     //newConnection代表有新的连接     connect(tcpServer, &QTcpServer::newConnection,             [=]()             {                 //取出建立好连接的套接字                 tcpSocket = tcpServer->nextPendingConnection(); ​                 //获取对方的IP和端口                 QString ip = tcpSocket->peerAddress().toString();                 quint16 port = tcpSocket->peerPort();                 QString temp = QString("[%1:%2]:成功连接").arg(ip).arg(port);                 ui->textEditRead->setText(temp); ​                 //readyRead代表读就绪                 connect(tcpSocket, &QTcpSocket::readyRead,                         [=]()                         {                             //从通信套接字中取出内容                             QByteArray array = tcpSocket->readAll();                             ui->textEditRead->append(array);                         }                         );             }             ); ​ } ​ ServerWidget::~ServerWidget() {     delete ui; } ​ void ServerWidget::on_buttonSend_clicked() {     if(NULL == tcpSocket)     {         return;     }     //获取编辑区内容     QString str = ui->textEditWrite->toPlainText();     //给对方发送数据, 使用套接字是tcpSocket     tcpSocket->write( str.toUtf8().data() ); ​ } ​ void ServerWidget::on_buttonClose_clicked() {     if(NULL == tcpSocket)     {         return;     } ​     //主动和客户端端口连接     tcpSocket->disconnectFromHost();     tcpSocket->close();     tcpSocket = NULL; } ​

serverwidget.h

 #ifndef SERVERWIDGET_H #define SERVERWIDGET_H ​ #include <QWidget> #include <QTcpServer> //监听套接字 #include <QTcpSocket> //通信套接字 ​ namespace Ui { class ServerWidget; } ​ class ServerWidget : public QWidget {     Q_OBJECT ​ public:     explicit ServerWidget(QWidget *parent = 0);     ~ServerWidget(); ​ private slots:     void on_buttonSend_clicked(); ​     void on_buttonClose_clicked(); ​ private:     Ui::ServerWidget *ui; ​     QTcpServer *tcpServer; //监听套接字     QTcpSocket *tcpSocket; //通信套接字 ​ }; ​ #endif // SERVERWIDGET_H

clientwidget.cpp

 #include "clientwidget.h" #include "ui_clientwidget.h" #include <QHostAddress> ​ ClientWidget::ClientWidget(QWidget *parent) :     QWidget(parent),     ui(new Ui::ClientWidget) {     ui->setupUi(this); ​     tcpSocket = NULL; ​     //分配空间,指定父对象     tcpSocket = new QTcpSocket(this); ​     setWindowTitle("客户端"); ​ ​     connect(tcpSocket, &QTcpSocket::connected,             [=]()             {                 ui->textEditRead->setText("成功和服务器建立好连接");             }             ); ​     connect(tcpSocket, &QTcpSocket::readyRead,             [=]()             {                 //获取对方发送的内容                 QByteArray array = tcpSocket->readAll();                 //追加到编辑区中                 ui->textEditRead->append(array);             } ​             ); ​ } ​ ClientWidget::~ClientWidget() {     delete ui; } ​ void ClientWidget::on_buttonConnect_clicked() {     //获取服务器ip和端口     QString ip = ui->lineEditIP->text();     qint16 port = ui->lineEditPort->text().toInt(); ​     //主动和服务器建立连接     tcpSocket->connectToHost(QHostAddress(ip), port); ​ } ​ void ClientWidget::on_buttonSend_clicked() {     //获取编辑框内容     QString str = ui->textEditWrite->toPlainText();     //发送数据     tcpSocket->write( str.toUtf8().data() ); ​ } ​ void ClientWidget::on_buttonClose_clicked() {     //主动和对方断开连接     tcpSocket->disconnectFromHost();     tcpSocket->close(); }

clientwidget.h

 #ifndef CLIENTWIDGET_H #define CLIENTWIDGET_H ​ #include <QWidget> #include <QTcpSocket> //通信套接字 ​ namespace Ui { class ClientWidget; } ​ class ClientWidget : public QWidget {     Q_OBJECT ​ public:     explicit ClientWidget(QWidget *parent = 0);     ~ClientWidget(); ​ private slots:     void on_buttonConnect_clicked(); ​     void on_buttonSend_clicked(); ​     void on_buttonClose_clicked(); ​ private:     Ui::ClientWidget *ui; ​     QTcpSocket *tcpSocket; //通信套接字 }; ​ #endif // CLIENTWIDGET_H ​

如果你觉得文章还不错,记得"点赞关注"

关注我的微信公众号【 加班猿 】可以获取更多内容