QT 学习 (TCP服务器通信)

QT编写TCP服务器通信总结: TCP服务器通信 , QT提供了服务器类QTcpServer和客户端类QTcpSocket

程序源码下载:https://download.csdn.net/download/dianzishi123/10849989

说明:上传的源码是最初始的,文档下的源码会根据不同时候的不同理解而改动

操作流程:

1. 创建一个基于MainWindows的UI工程,在工程管理文件(.pro文件)中添加 network 模块 ,并设置UI界面

2. 使用QTcpServer类创建一个TCP服务器对象并获取主机IP

3. 监听端口, 并设置最大监听数量

4. 信号和槽的处理(信号:新连接; 客户端连入信号; 读取客户端数据信号; 客户端断开信号等)

步骤1:

(1). 工程目录:

(2). 在Server.pro文件中添加network模块

(3). UI界面

(4) . 改变使用的对象名称(就是变量名,不使用默认的);选中要改变的控件,点击鼠标右键选择"改变对象名称..."

(5). 有两个槽函数不用自己手动连接(打开服务器和发送的槽函数)

选择"打开服务器"  或  "发送"控件点击鼠标右键选择 "转到槽..."

设置完UI界面下面开始编写控制程序

mainwindow.cpp文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkInterface>
#include <QDebug>
#include <QPalette>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setMaximumSize(460,268);//设置固定界面大小
    setMinimumSize(460,268);
    Init();
}

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

QString MainWindow::getHostIpAddrs()  //获取本机IP地址
{
    QString ip;
    QList<QHostAddress> ipAddrs = QNetworkInterface::allAddresses();
    for (int i = 0; i < ipAddrs.size(); ++i)
    {
        if (ipAddrs.at(i) != QHostAddress::LocalHost && ipAddrs.at(i).toIPv4Address())
        {
            // 如果这个地址不是127.0.0.1,并且是IPv4的地址,就将其赋值给ip,并结束for循环
            ip = ipAddrs.at(i).toString();
            break;
        }
    }
    // 如果ip为空,则将其赋值为127.0.0.1
    if (ip.isEmpty())
        ip = QHostAddress(QHostAddress::LocalHost).toString();
    return ip;
}


//初始化函数
void MainWindow::Init()
{
    // 1.创建一个服务器
    tcpServer = new QTcpServer(this);

    // 2.获取网卡信息
    QString ipAddr = getHostIpAddrs();
    ui->SerPort_Edit->setText("8080");//打开时设置默认端口
    ui->SerIP_Edit->setText(ipAddr);//把获取的服务器IP填到对应的IP 行


    //设置打开服务器按钮的背景颜色
    pal=ui->openButton->palette();
    pal.setColor(QPalette::Button,Qt::cyan);
    ui->openButton->setPalette(pal);
    ui->openButton->setAutoFillBackground(true);
    ui->openButton->setFlat(true);
}


//开启TCP服务器按钮
void MainWindow::on_openButton_clicked()
{
    // 1. 开启服务监听端口
    QString serIP = ui->SerIP_Edit->text();//获取IP
    QString serPort = ui->SerPort_Edit->text();//获取端口
    bool ret;
    if(ui->openButton->text()=="打开服务器")  //打开TCP服务
    {
        ret = tcpServer->listen(QHostAddress(serIP),serPort.toInt());
        if(!ret)//服务器打开失败
        {
            ui->receText->append("未打开TCP服务!");//追加显示
            return;
        }
        ui->receText->append("成功打开TCP服务!");
        ui->openButton->setText("关闭服务器");
        tcpServer->setMaxPendingConnections(100);//设置最大连接数量

    }
    else if(ui->openButton->text()=="关闭服务器") //关闭TCP服务
    {
        ui->receText->append("成功关闭TCP服务!");
        ui->openButton->setText("打开服务器");
        tcpServer->close();

    }
    connect(tcpServer,SIGNAL(newConnection()),
            this,SLOT(doProcessNewConnect()));//新连接信号和槽

    connect(tcpServer,SIGNAL(acceptError(QAbstractSocket::SocketError)),
            this,SLOT(doProcessAcceptError(QAbstractSocket::SocketError)));//接收错误处理槽

}

//接收错误信息处理
void MainWindow::doProcessAcceptError(QAbstractSocket::SocketError)
{

}


//新客户端连接槽函数
void MainWindow::doProcessNewConnect()
{
    client = tcpServer->nextPendingConnection();//获取客户端描述符
    clients.append(client);//获取所有的客户端连接
    //读取信息
    connect(client,SIGNAL(readyRead()),
            this,SLOT(doProcessReadyRead()));//客户端读取内容信号连接槽
    connect(client,SIGNAL(disconnected()),
            this,SLOT(doProcessDisconnected()));//客户端断开连接信号和槽

    //客户端的连入
    connect(client,SIGNAL(connected()),
            this,SLOT(doProcessConnected()));
}

//客户端读取信息
void MainWindow::doProcessReadyRead()
{
    client = (QTcpSocket *)this->sender();
    QString str1 = QString("客户端[%1:%2]说:").arg(client->peerAddress().toString())
                                            .arg(client->peerPort());
    QString str2;
    while(!client->atEnd())//没有读到末尾一直读
    {
         str2.append(QString(client->readAll()));
         qDebug()<<"hhhhhhhhhh"<<str2;
    }
    QString msg = QString("%1%2").arg(str1).arg(str2);
    ui->receText->append(msg);
}

//客户端断开连接
void MainWindow::doProcessDisconnected()
{
    client = (QTcpSocket *)this->sender();
    QString msg = QString("客户端[%1:%2]退出!").arg(client->peerAddress().toString()).arg(client->peerPort());
    ui->receText->append(msg);

    //删除断开的客户端
    for(int i=0;i<clients.length();i++)
    {
        if(clients.at(i)->peerAddress()==client->peerAddress())
        {
            if(clients.at(i)->peerPort()==client->peerPort())
            {
                clients.removeAt(i);
                break;
            }
        }
    }
}

//发送按钮
void MainWindow::on_sendButton_clicked()
{
    QString clientIp = ui->clientIpEdit->text();//获取客户端IP
    QString clientPort = ui->clientPortEdit->text();//获取客户端端口

    for(int i=0;i<clients.length();i++)//遍历客户端
    {
        if(clients.at(i)->peerAddress().toString()==clientIp)
        {
            if(clients.at(i)->peerPort()==clientPort.toUInt())
            {
                QString msg = ui->sendLineEdit->text();
                clients.at(i)->write(msg.toLatin1());
                break;
            }
        }
    }
}

void MainWindow::doProcessConnected()
{
    client = (QTcpSocket *)this->sender();
    QString msg = QString("客户端[%1:%2]连入:")
            .arg(client->peerAddress().toString())
            .arg(client->peerPort());
    ui->receText->append(msg);
}

mainwindow.h文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_openButton_clicked();//打开服务器点击按钮槽函数
    void on_sendButton_clicked();//发送按钮点击槽函数

    //处理客户端连接断开发送数据等槽函数
    void doProcessNewConnect();
    void doProcessAcceptError(QAbstractSocket::SocketError);
    void doProcessDisconnected();
    void doProcessReadyRead();
    void doProcessConnected();


private:
    Ui::MainWindow *ui;
    void Init();//初始化函数
    QString getHostIpAddrs();//获取本机IP

    QPalette pal;//设置按钮背景颜色

    QTcpServer *tcpServer;//定义一个TCP服务器
    QList<QTcpSocket *>clients;   //定义连接的客户端
    QTcpSocket *client;
};

#endif // MAINWINDOW_H

main.cpp文件:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

猜你喜欢

转载自blog.csdn.net/dianzishi123/article/details/85013070
今日推荐