温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

QT网络编程Tcp下C/S架构如何实现即时通信

发布时间:2021-08-11 11:03:30 来源:亿速云 阅读:253 作者:小新 栏目:编程语言

这篇文章主要介绍QT网络编程Tcp下C/S架构如何实现即时通信,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面。

#ifndef TCPCLIENT_H #define TCPCLIENT_H   #include <QDialog> #include <QListWidget> #include <QLineEdit> #include <QPushButton> #include <QLabel> #include <QGridLayout> #include <QtNetWork/QHostAddress> #include <QtNetWork/QTcpSocket>   class TcpClient : public QDialog {  Q_OBJECT   public:  TcpClient(QWidget *parent = 0,Qt::WindowFlags f=0);  ~TcpClient(); private:  QListWidget *contentListWidget;  QLineEdit *sendLineEdit;  QPushButton *sendBtn;  QLabel *userNameLabel;  QLineEdit *userNameLineEdit;  QLabel *serverIPLabel;  QLineEdit *serverIPLineEdit;  QLabel *portLabel;  QLineEdit *portLineEdit;  QPushButton *enterBtn;  QGridLayout *mainLayout;  bool status;  int port;  QHostAddress *serverIP;  QString userName;  QTcpSocket *tcpSocket; public slots:  void slotEnter();  void slotConnected();  void slotDisconnected();  void dataReceived();  void slotSend(); };   #endif // TCPCLIENT_H

有一个加入服务器的按钮,还有一个发送消息的按钮,在头文件,先定义两个函数。

#include "tcpclient.h" #include <QMessageBox> #include <QHostInfo>   TcpClient::TcpClient(QWidget *parent,Qt::WindowFlags f)  : QDialog(parent,f) {  setWindowTitle(tr("TCP Client"));    contentListWidget = new QListWidget;    sendLineEdit = new QLineEdit;  sendBtn = new QPushButton(tr("send"));    userNameLabel = new QLabel(tr("name"));  userNameLineEdit = new QLineEdit;    serverIPLabel = new QLabel(tr("server"));  serverIPLineEdit = new QLineEdit;    portLabel = new QLabel(tr("port"));  portLineEdit = new QLineEdit;    enterBtn= new QPushButton(tr("join chat"));    mainLayout = new QGridLayout(this);  mainLayout->addWidget(contentListWidget,0,0,1,2);  mainLayout->addWidget(sendLineEdit,1,0);  mainLayout->addWidget(sendBtn,1,1);  mainLayout->addWidget(userNameLabel,2,0);  mainLayout->addWidget(userNameLineEdit,2,1);  mainLayout->addWidget(serverIPLabel,3,0);  mainLayout->addWidget(serverIPLineEdit,3,1);  mainLayout->addWidget(portLabel,4,0);  mainLayout->addWidget(portLineEdit,4,1);  mainLayout->addWidget(enterBtn,5,0,1,2);    status = false;    port = 8010;  portLineEdit->setText(QString::number(port));    serverIP =new QHostAddress();    connect(enterBtn,SIGNAL(clicked()),this,SLOT(slotEnter()));  connect(sendBtn,SIGNAL(clicked()),this,SLOT(slotSend()));    sendBtn->setEnabled(false); }   TcpClient::~TcpClient() {   }   void TcpClient::slotEnter() {  if(!status)  {   QString ip = serverIPLineEdit->text();   if(!serverIP->setAddress(ip))   {    QMessageBox::information(this,tr("error"),tr("server ip address error!"));    return;   }     if(userNameLineEdit->text()=="")   {    QMessageBox::information(this,tr("error"),tr("User name error!"));    return;   }     userName=userNameLineEdit->text();     tcpSocket = new QTcpSocket(this);   connect(tcpSocket,SIGNAL(connected()),this,SLOT(slotConnected()));   connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));   connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));     tcpSocket->connectToHost(*serverIP,port);     status=true;  }  else  {   int length=0;   QString msg=userName+tr(":Leave Chat Room");   if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg. length())   {    return;   }     tcpSocket->disconnectFromHost();     status=false;  } }   void TcpClient::slotConnected() {  sendBtn->setEnabled(true);  enterBtn->setText(tr("离开"));    int length=0;  QString msg=userName+tr(":Enter Chat Room");  if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length())  {   return;  } }   void TcpClient::slotSend() {  if(sendLineEdit->text()=="")  {   return ;  }    QString msg=userName+":"+sendLineEdit->text();    tcpSocket->write(msg.toLatin1(),msg.length());  sendLineEdit->clear(); }   void TcpClient::slotDisconnected() {  sendBtn->setEnabled(false);  enterBtn->setText(tr("join chat")); }   void TcpClient::dataReceived() {  while(tcpSocket->bytesAvailable()>0)  {   QByteArray datagram;   datagram.resize(tcpSocket->bytesAvailable());     tcpSocket->read(datagram.data(),datagram.size());     QString msg=datagram.data();   contentListWidget->addItem(msg.left(datagram.size()));  } }

实现界面布局。在Enter槽函数中,确定加入还是离开的服务器的功能。如果加入了,就将消息,写到tcpsocket中,构造消。

服务端的头文件:

#ifndef TCPSERVER_H #define TCPSERVER_H   #include <QDialog> #include <QListWidget> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QGridLayout> #include "server.h"   class TcpServer : public QDialog {  Q_OBJECT   public:  TcpServer(QWidget *parent = 0,Qt::WindowFlags f=0);  ~TcpServer(); private:  QListWidget *ContentListWidget;  QLabel *PortLabel;  QLineEdit *PortLineEdit;  QPushButton *CreateBtn;  QGridLayout *mainLayout;  int port;  Server *server; public slots:  void slotCreateServer();  void updateServer(QString,int); };   #endif // TCPSERVER_H

这是服务端的界面的,把消息显示而已。实现这个布局。

#include "tcpserver.h"   TcpServer::TcpServer(QWidget *parent,Qt::WindowFlags f)  : QDialog(parent,f) {  setWindowTitle(tr("TCP Server"));    ContentListWidget = new QListWidget;    PortLabel = new QLabel(tr(" port"));  PortLineEdit = new QLineEdit;    CreateBtn = new QPushButton(tr("create chat"));  mainLayout = new QGridLayout(this);  mainLayout->addWidget(ContentListWidget,0,0,1,2);  mainLayout->addWidget(PortLabel,1,0);  mainLayout->addWidget(PortLineEdit,1,1);  mainLayout->addWidget(CreateBtn,2,0,1,2);    port=8010;  PortLineEdit->setText(QString::number(port));    connect(CreateBtn,SIGNAL(clicked()),this,SLOT(slotCreateServer())); }   TcpServer::~TcpServer() {   }   void TcpServer::slotCreateServer() {  server = new Server(this,port);  connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));    CreateBtn->setEnabled(false); }   void TcpServer::updateServer(QString msg,int length) {  ContentListWidget->addItem(msg.left(length)); }

创建TCP的套接字,以便实现服务端和客户端的通信。

#ifndef TCPCLIENTSOCKET_H #define TCPCLIENTSOCKET_H   #include <QtNetWork/QTcpSocket> #include <QObject>   class TcpClientSocket : public QTcpSocket {  Q_OBJECT public:  TcpClientSocket(); signals:  void updateClients(QString,int);  void disconnected(int); protected slots:  void dataReceived();  void slotDisconnected(); };   #endif // TCPCLIENTSOCKET_H

以上是头文件,具体的是:

#include "tcpclientsocket.h"   TcpClientSocket::TcpClientSocket() {  connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));  connect(this,SIGNAL(disconnected()),this,SLOT(slotDisconnected())); }   void TcpClientSocket::dataReceived() {  while(bytesAvailable()>0)  {   int length = bytesAvailable();   char buf[1024];   read(buf,length);     QString msg=buf;   emit updateClients(msg,length);  } }   void TcpClientSocket::slotDisconnected() {  emit disconnected(this->socketDescriptor()); }

实现服务器,头文件:

#ifndef SERVER_H #define SERVER_H   #include <QtNetWork/QTcpServer> #include <QObject> #include "tcpclientsocket.h"   class Server : public QTcpServer {  Q_OBJECT public:  Server(QObject *parent=0,int port=0);  QList<TcpClientSocket*> tcpClientSocketList; signals:  void updateServer(QString,int); public slots:  void updateClients(QString,int);  void slotDisconnected(int); protected:  void incomingConnection(int socketDescriptor); };   #endif // SERVER_H
#include "server.h"   Server::Server(QObject *parent,int port)  :QTcpServer(parent) {  listen(QHostAddress::Any,port); }   void Server::incomingConnection(int socketDescriptor) {  TcpClientSocket *tcpClientSocket = new TcpClientSocket;  connect(tcpClientSocket,SIGNAL(updateClients(QString,int)),this,SLOT(updateClients(QString,int)));  connect(tcpClientSocket,SIGNAL(disconnected(int)),this,SLOT(slotDisconnected(int)));    tcpClientSocket->setSocketDescriptor(socketDescriptor);    tcpClientSocketList.append(tcpClientSocket); }   void Server::updateClients(QString msg,int length) {  emit updateServer(msg,length);  for(int i=0;i<tcpClientSocketList.count();i++)  {   QTcpSocket *item = tcpClientSocketList.at(i);   if(item->write(msg.toLatin1(),length)!=length)   {    continue;   }  } }   void Server::slotDisconnected(int descriptor) {  for(int i=0;i<tcpClientSocketList.count();i++)  {   QTcpSocket *item = tcpClientSocketList.at(i);   if(item->socketDescriptor()==descriptor)   {    tcpClientSocketList.removeAt(i);    return;   }  }  return; }

实现后的界面:

QT网络编程Tcp下C/S架构如何实现即时通信

以上是“QT网络编程Tcp下C/S架构如何实现即时通信”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI