虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > C/C++编程 > QT网络编程Tcp下C/S架构的即时通信实例

QT网络编程Tcp下C/S架构的即时通信实例
类别:C/C++编程   作者:码皇   来源:互联网   点击:

下面小编就为大家带来一篇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_OBJECTpublic: 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_OBJECTpublic: 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架构的即时通信实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关热词搜索: 即时通信架构