Qt-TCP通信-简易仿QQ项目

今天带来一个简单的聊天项目,项目不难,客户端和服务器端一共只有400多行代码,这个程序的缺点是无法实现广播与组播,只能连接一个客户端。
先来看程序的运行效果:
在这里插入图片描述

1服务器端的设计:

项目框架:
在这里插入图片描述
因为这个有网络部分,所以在.pro文件里添加QT+=network
dialog.h:

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostInfo>
#include <QDebug>
namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT
private:
//   QLabel *LabListen;
//   QLabel *LabSocketState;
   QTcpServer *tcpServer;
   QTcpSocket *tcpSocket;
   QString getLocalIP();
protected:
   void closeEvent(QCloseEvent *);
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
private slots:
   void onNewConnection();
   void onSocketStatueChange(QAbstractSocket::SocketState socketState);
   void onCilentConnected();
   void onClientDisConnected();
   void onSocketReadyRead();

   void on_btn_start_listen_clicked();

   void on_btn_stop_listen_clicked();

   void on_btn_clear_clicked();

   void on_btn_exit_clicked();

   void on_btn_send_clicked();

private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H

dialog.cpp:

#include "dialog.h"
#include "ui_dialog.h"
#pragma execution_character_set("utf-8")

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    ui->label_listenstate->setText("监听状态");
    ui->label_socketstate->setText("Socket状态");
    QString localIP=getLocalIP();
    this->setWindowTitle(this->windowTitle()+"---本机IP:"+localIP);
    ui->comboBox->addItem(localIP);
    tcpServer=new QTcpServer(this);
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
}
//获取本机IPv4地址
QString Dialog::getLocalIP()
{
    QString hostName=QHostInfo::localHostName();
    QHostInfo hostInfo=QHostInfo::fromName(hostName);
    QString localIP="";
    QList<QHostAddress> addlist=hostInfo.addresses();
    if(!addlist.isEmpty()){
        for(int i=0;i<addlist.count();i++){
            QHostAddress aHost=addlist.at(i);
            if(QAbstractSocket::IPv4Protocol==aHost.protocol()){
                localIP=aHost.toString();
            }
        }

    }
    return localIP;
}

void Dialog::closeEvent(QCloseEvent *)
{
   qDebug()<<"ok";

}

//开始监听
void Dialog::on_btn_start_listen_clicked()
{
    //IP地址
    QString IP=ui->comboBox->currentText();
    quint16 port=ui->spinBox->value();
    QHostAddress addr(IP);
    tcpServer->listen(addr,port);
    ui->plainTextEdit->appendPlainText("---开始监听----");
    ui->plainTextEdit->appendPlainText("---服务器地址:"+tcpServer->serverAddress().toString());
    ui->plainTextEdit->appendPlainText("---服务器端口"+QString::number(tcpServer->serverPort()));
    ui->btn_start_listen->setEnabled(false);
    ui->btn_stop_listen->setEnabled(true);
    ui->label_listenstate->setText("监听状态: 正在监听");
}


void Dialog::onNewConnection()
{
    //获取socket
    tcpSocket=tcpServer->nextPendingConnection();
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(onClientConnected()));
    onCilentConnected();
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(onClientDisConnected()));
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStatueChange(QAbstractSocket::SocketState)));
    onSocketStatueChange(tcpSocket->state());
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));

}
//socket状态变化
void Dialog::onSocketStatueChange(QAbstractSocket::SocketState socketState)
{
    switch (socketState) {
    case QAbstractSocket::UnconnectedState:
        ui->label_socketstate->setText("socket状态: UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        ui->label_socketstate->setText("socket状态: HostLookupState");
    case QAbstractSocket::ConnectingState:
        ui->label_socketstate->setText("socket状态: ConnectingState");
    case QAbstractSocket::ConnectedState:
         ui->label_socketstate->setText("socket状态: ConnectedState");
    case QAbstractSocket::BoundState:
         ui->label_socketstate->setText("socket状态: BoundState");
    case QAbstractSocket::ClosingState:
         ui->label_socketstate->setText("socket状态: ClosingState");
    case QAbstractSocket::ListeningState:
         ui->label_socketstate->setText("socket状态: ListeningState");
    }

}
//客户端接入时
void Dialog::onCilentConnected()
{
    ui->plainTextEdit->appendPlainText("--client socket connected");
    ui->plainTextEdit->appendPlainText("--peer address:"+tcpSocket->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("--peer port:"+QString::number(tcpSocket->peerPort()));;



}
//客户端断开连接时
void Dialog::onClientDisConnected()
{
    ui->plainTextEdit->appendPlainText("--client socket connected");
    tcpSocket->deleteLater();

}


void Dialog::on_btn_stop_listen_clicked()
{
    if(tcpServer->isListening()){
        tcpServer->close();
        ui->btn_start_listen->setEnabled(true);
        ui->btn_stop_listen->setEnabled(false);
        ui->label_listenstate->setText("监听状态:已停止监听");
    }
}



void Dialog::on_btn_send_clicked()
{
    QString msg=ui->lineEdit->text();
    ui->plainTextEdit->appendPlainText("[out]"+msg);
    ui->lineEdit->clear();
    ui->lineEdit->setFocus();
    QByteArray str=msg.toUtf8();
    str.append('\n');
    tcpSocket->write(str);

}
//读取缓冲区文本
void Dialog::onSocketReadyRead()
{
    while(tcpSocket->canReadLine()){
        ui->plainTextEdit->appendPlainText("[in]"+tcpSocket->readLine());
    }

}
void Dialog::on_btn_clear_clicked()
{
    ui->plainTextEdit->clear();

}

void Dialog::on_btn_exit_clicked()
{
    QApplication *app;
    app->exit(0);

}
Dialog::~Dialog()
{
    delete ui;
}



dialog.ui:
在这里插入图片描述
在这里插入图片描述
以上就完成了服务器端的设计

2 客户端的设计:

项目框架:
在这里插入图片描述
同样因为这个有网络部分,所以在.pro文件里添加QT+=network
dialog.h:

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostInfo>
#include <QDebug>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT
private:
    QTcpSocket *tcpClient;
    QString getlocalIP_client();
protected:
    void closeEvent(QCloseEvent *event);

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private slots:
    void onConnected();
    void onDisConnected();
    void onSocketStateChanged(QAbstractSocket::SocketState socketstate);
    void onSocketReadyRead();

    void on_btn_connect_clicked();

    void on_btn_cut_clicked();

    void on_btn_clear_clicked();

    void on_btn_exit_clicked();

    void on_btn_send_clicked();

private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H

dialog.cpp:

#include "dialog.h"
#include "ui_dialog.h"
#pragma execution_character_set("utf-8")
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    tcpClient=new QTcpSocket(this);
    ui->label_socketstate->setText("Socket 状态:");
    QString localIP=getlocalIP_client();
    this->setWindowTitle(this->windowTitle()+"---本机IP:"+localIP);
    ui->comboBox->addItem(localIP);
    //客户端
    connect(tcpClient,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(tcpClient,SIGNAL(disconnected()),this,SLOT(onDisConnected()));
    connect(tcpClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,
            SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
    connect(tcpClient,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
    //按钮
    connect(ui->btn_connect,SIGNAL(clicked(bool)),this,SLOT(on_btn_connect_clicked()));
    connect(ui->btn_cut,SIGNAL(clicked(bool)),this,SLOT(on_btn_cut_clicked()));
    connect(ui->btn_clear,SIGNAL(clicked(bool)),this,SLOT(on_btn_clear_clicked()));
    connect(ui->btn_exit,SIGNAL(clicked(bool)),SLOT(on_btn_exit_clicked()));
    connect(ui->btn_send,SIGNAL(clicked(bool)),this,SLOT(on_btn_send_clicked()));
            
}
void Dialog::closeEvent(QCloseEvent *event){
    qDebug()<<"ok1";
}

QString Dialog::getlocalIP_client(){
    QString hostName=QHostInfo::localHostName();
    QHostInfo hostInfo=QHostInfo::fromName(hostName);
    QString localIP="";
    QList<QHostAddress> addlist=hostInfo.addresses();
    if(!addlist.isEmpty()){
        for(int i=0;i<addlist.count();i++){
            QHostAddress aHost=addlist.at(i);
            if(QAbstractSocket::IPv4Protocol==aHost.protocol()){
                localIP=aHost.toString();
                break;
            }
        }

    }
    return localIP;
}

void Dialog::onConnected()
{
    ui->plainTextEdit->appendPlainText("--已连接到服务器");
    ui->plainTextEdit->appendPlainText("--peer address"+tcpClient->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("--peer port:"+QString::number(tcpClient->peerPort()));
    ui->btn_connect->setEnabled(false);
    ui->btn_cut->setEnabled(true);
    
}

void Dialog::onDisConnected()
{
    ui->plainTextEdit->appendPlainText("已断开与服务器之间的连接");
    ui->btn_connect->setEnabled(true);
    ui->btn_cut->setEnabled(false);
    
}

void Dialog::onSocketStateChanged(QAbstractSocket::SocketState socketstate)
{
    switch (socketstate) {
    case QAbstractSocket::UnconnectedState:
        ui->label_socketstate->setText("socket状态: UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        ui->label_socketstate->setText("socket状态: HostLookupState");
    case QAbstractSocket::ConnectingState:
        ui->label_socketstate->setText("socket状态: ConnectingState");
    case QAbstractSocket::ConnectedState:
         ui->label_socketstate->setText("socket状态: ConnectedState");
    case QAbstractSocket::BoundState:
         ui->label_socketstate->setText("socket状态: BoundState");
    case QAbstractSocket::ClosingState:
         ui->label_socketstate->setText("socket状态: ClosingState");
    case QAbstractSocket::ListeningState:
         ui->label_socketstate->setText("socket状态: ListeningState");
    }

    
}

void Dialog::on_btn_connect_clicked()
{
    QString addr=ui->comboBox->currentText();
    quint16 port=ui->spinBox->value();
    tcpClient->connectToHost(addr,port);
}

void Dialog::on_btn_cut_clicked()
{
    if(tcpClient->state()==QAbstractSocket::ConnectedState){
        tcpClient->disconnectFromHost();
    }

}

void Dialog::on_btn_clear_clicked()
{
    ui->plainTextEdit->clear();

}

void Dialog::on_btn_exit_clicked()
{
    QApplication *app;
    app->exit();
}

void Dialog::on_btn_send_clicked()
{
    QString msg=ui->lineEdit->text();
    ui->plainTextEdit->appendPlainText("[out]"+msg);
    ui->lineEdit->clear();
    ui->lineEdit->setFocus();
    QByteArray str=msg.toUtf8();
    str.append('\n');
    tcpClient->write(str);



}
void Dialog::onSocketReadyRead()
{
    while(tcpClient->canReadLine()){
        ui->plainTextEdit->appendPlainText("[in]"+tcpClient->readLine());
    }

}

Dialog::~Dialog()
{
    delete ui;
}




以上就完成了这个项目,这个项目不难,我从昨天晚上开始写了一点,今天早上写了一点就完了,主要为了复习QT网络的知识,如果看不懂,可以百度,谷歌,或者私信我。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值