关于qt:Qt中的TCP服务端和客户端互发消息

22次阅读

共计 5113 个字符,预计需要花费 13 分钟才能阅读完成。

Qt 中的 TCP 服务端和客户端互发音讯

作者:hackett

微信公众号:加班猿

废话不多说,上演示成果

因为咱们用到 socketLamda表达式,所以工程.pro 文件须要增加对应的库

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

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

一、服务端

服务端的 UI 界面布局:

2 个 PushButton(send,close)

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

新建一个监听套接字,监听端口号为 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(发送内容,接管内容)

客户端连贯按钮被动与服务端建设连贯

 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
 ​

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

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

正文完
 0