QT网络编程Tcp下C/S架构的即时通信实例
更新时间:2020年4月25日 17:30 点击:1887
先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面。
#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架构的即时通信实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
- 这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-28
- 本篇文章主要介绍了C# Socket的TCP通讯,socket通讯方式有两种:同步和异步,详细的介绍了这两种方法,有兴趣的可以了解一下。...2020-06-25
- 这篇文章主要介绍了C#基于TCP协议的服务器端和客户端通信编程的基础教程,文中讲解了C#中TCP编程主要相关的TcpListener类与TcpClient类用法,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了CocosCreator MVC架构,同学们在制作游戏过程中,尽量使用一些架构,会避免很多问题...2021-04-16
- 这篇文章主要介绍了使用C#实现基于TCP和UDP协议的网络通信程序的示例,文中分别编写了基本的服务器端和客户端,代码十分简单,需要的朋友可以参考下...2020-06-25
- windows 2003 连接限制TCP连接限制。目前我们有一台windows 2003 SP2的操作系统,提供web服务,还有一个自主开发的提供音频直播的服务...2016-01-27
- 首先,学好计算机网络知识真的很重要。虽然,学不好不会影响理解下面这个关于宏观讲解,但是,学好了可以自己打渔吃,学不好就只能知道眼前有鱼吃却打不到渔。在Java中网络程序有2种协议:TCP和UDP,下面可以和小编一起学习下...2020-04-25
thinkPHP5.0框架整体架构总览【应用,模块,MVC,驱动,行为,命名空间等】
这篇文章主要介绍了thinkPHP5.0框架整体架构,简单介绍了thinkPHP5.0的应用,模块,MVC,驱动,行为,命名空间等概念与基本用法,需要的朋友可以参考下...2017-04-03Android MVVM架构实现RecyclerView列表详解流程
MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开...2021-10-30ASP.NET MVC5网站开发之业务逻辑层的架构和基本功能 (四)
这篇文章主要为大家详细介绍了ASP.NET MVC5网站开发之业务逻辑层的架构和基本功能,感兴趣的小伙伴们可以参考一下...2021-09-22- 这篇文章主要为大家详细介绍了ASP.NET三层架构,如何实现三层架构,本文为大家揭晓,感兴趣的小伙伴们可以参考一下...2021-09-22
C++ boost::asio编程-异步TCP详解及实例代码
这篇文章主要介绍了C++ boost::asio编程-异步TCP详解及实例代码的相关资料,需要的朋友可以参考下...2020-04-25- 下面小编就为大家带来一篇浅谈socket TCP编程中connect的一些坑。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了ipv6实现tcp编程示例,需要的朋友可以参考下...2020-04-25
- 我们按照由简至繁的步骤,搭建一个最小型的高可用的Redis服务。本文通过四种方案给大家介绍包含每种方案的优缺点及详细解说,具体内容详情跟随小编一起看看吧...2021-06-19
- TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 基于IP的传输层协议。TCP在IP报文的协议号是6。TCP是一个超级麻烦的协议,而它又是互联网的基础,也是每个程序员必备的基本功。本文将详细介绍PHP Swoole与TCP三次握手。...2021-05-27
- 这篇文章主要为大家详细介绍了ASP.NET MVC5网站开发之展示层架构,感兴趣的小伙伴们可以参考一下...2021-09-22
- 这篇文章主要介绍了Java 微服务架构的相关资料,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下...2021-02-04
- 这篇文章主要为大家详细介绍了mysql 5.7 docker 主从复制架构搭建教程,感兴趣的小伙伴们可以参考一下...2016-08-23
- 下面小编就为大家带来一篇QT网络编程UDP下C/S架构广播通信(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25