自学内容网 自学内容网

【无标题】

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include<QLocalServer>
#include<QLocalSocket>
#include<QMessageBox>
#include<QDataStream>
 
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 
private slots:
    void on_pushButton_clicked();
 
private:
    Ui::Widget *ui;
    QLocalServer *localserver;//服务端
    QLocalSocket*localsocket=nullptr;//套接字
 
};
#endif // WIDGET_H

cpp文件:

#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("服务器端");
    localserver=new QLocalServer(this);
    localserver->listen("Good People");//Good People作为连接字符
    connect(localserver,&QLocalServer::newConnection,[=]()
    {
        localsocket=localserver->nextPendingConnection();//获取连接的套接字
        connect(localsocket,&QLocalSocket::readyRead,[=]()//如果有可读数据的话
        {
            QByteArray block;
            block=localsocket->readAll();
            QString S=block.data();
            ui->textEdit->append(QString("客户端:%1").arg(S));
        });
 
    });
}
 
Widget::~Widget()
{
    delete ui;
}
 
 
void Widget::on_pushButton_clicked()//发送数据
{
    if(ui->lineEdit->text().isEmpty())
    {
        QMessageBox::information(this,"提示信息","请输入内容",QMessageBox::Ok);
        return;
    }
    ui->textEdit->setText(QString("服务器端:%1").arg(ui->lineEdit->text()));//设置内容
    if(localsocket->isValid())
    {
        QString S=ui->lineEdit->text();
        localsocket->write(S.toUtf8());//发送消息
    }
 
}

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include<QLocalSocket>
#include<QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 
private slots:
    void on_pushButton_clicked();
 
    void on_pushButton_2_clicked();
 
private:
    Ui::Widget *ui;
    QLocalSocket * localsocket;//套接字
};
#endif // WIDGET_H
.cpp文件:

#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    localsocket=new QLocalSocket(this);
    setWindowTitle("客户端");
    connect(localsocket,&QLocalSocket::readyRead,[=]()
    {
        QByteArray block;
        block=localsocket->readAll();//读取信息
        ui->textEdit->append(QString("服务器:%1").arg(block.data()));//聊天框添加信息
    });
 
}
 
Widget::~Widget()
{
    delete ui;
}
 
 
void Widget::on_pushButton_clicked()//连接
{
    localsocket->abort();//先断开
    localsocket->connectToServer("Good People");//连接
}
 
void Widget::on_pushButton_2_clicked()//发送
{
    if(ui->lineEdit->text().isEmpty())
    {
        QMessageBox::information(this,"提示信息","请输入内容。",QMessageBox::Ok);
        return;
    }
    if(localsocket->isValid())
    {
        localsocket->write(ui->lineEdit->text().toUtf8());
        ui->textEdit->append(QString("客户端:%1").arg(ui->lineEdit->text()));
    }
 
 
}

例子:写入和读取数据

    QSharedMemory memory;创建对象
    memory.setKey("1000");//设置标识
 
    //写入数据
    if(memory.isAttached())//已经连接的话
    {
        memory.detach();//断开连接
    }
    QString Str="SharedMemory";
 
    QBuffer buffer;
    buffer.open(QBuffer::ReadWrite);
    QDataStream S(&buffer);
    S<<Str;//将数据写到缓存中
    memory.create(buffer.size());//创建共享内存
    memory.lock();//上锁
    char * M=(char *)memory.data();//获取memory的指针
    const char *N=buffer.data().data();//获取缓存的指针
    memcpy(M,N,buffer.size());//把数据复制到共享内存中
    memory.unlock();//解锁
 
    //读取数据
    memory.attach();//连接共享内存
    QBuffer buffer1;
    QDataStream in(&buffer);
    QString Str1;
 
    memory.lock();//上锁
    buffer.setData((char*)memory.constData(),memory.size());//存入数据
    buffer.open(QBuffer::ReadOnly);//只读模式
    in>>Str1;//读取数据
    memory.unlock();//解锁
 
    memory.detach();//断开连接
    qDebug()<<Str1;

.h文件:

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include<QSharedMemory>
#include<QBuffer>
#include<QMessageBox>
#include<QDataStream>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 
private slots:
    void on_pushButton_clicked();
 
    void on_pushButton_2_clicked();
 
    void on_pushButton_3_clicked();
 
private:
    Ui::Widget *ui;
    QSharedMemory sharedmemory;//共享内存
};
#endif // WIDGET_H

main函数:

#include "widget.h"
 
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w1;
    w1.setWindowTitle("widget1");
    w1.show();//进程1
    Widget w2;
    w2.setWindowTitle("widget2");
    w2.show();//进程2
    return a.exec();
}
这里解释一下为什么要有断开连接的按钮:

经过多次测试发现 :

A端发完数据,B端接收数据后,A端需要主动断开连接后B端才能正常发送数据。

(懂的大佬请在评论区解释一下)

.h文件:

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include<QProcess>
#include<QMessageBox>
#include<QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 
private slots:
    void on_pushButton_clicked();
 
    void on_pushButton_2_clicked();
private:
    Ui::Widget *ui;
    QProcess *process;
};
#endif // WIDGET_H

.cpp文件:

#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("主进程");
    process=new QProcess;
    connect(process,&QProcess::readyReadStandardOutput,[=]()//读取信息
    {
        QString S=process->readAllStandardOutput().data();
        ui->textEdit->append(QString("子线程:%1").arg(S));
    });
 
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::on_pushButton_clicked()//打开子进程
{
    //子线程的开启
    process->start("D:/Qt_data/build-QProcess_text1-Desktop_Qt_5_9_9_MinGW_32bit-Debug/debug/QProcess_text1.exe");
 
}
 
void Widget::on_pushButton_2_clicked()//发送数据
{
 
    if(ui->lineEdit->text().isEmpty())
    {
        QMessageBox::information(this,"提示信息","输入框不能为空。",QMessageBox::Ok);
        return;
    }
    if(process->Running)
    {
        QString S=ui->lineEdit->text();//获取lineEdit中的内容
        process->write(S.toStdString().c_str());//写入数据
        ui->textEdit->append("父线程:"+S);//在聊天框显示内容
    }
    return;
 
}

.h文件:
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include<QFile>
#include<QSocketNotifier>
#include<QBuffer>
#include<QMessageBox>
#include<QFuture>
#include<QtConcurrent>
#include<QIODevice>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
 
private slots:
    void on_pushButton_clicked();
    void readStdin();//读取数据
 
private:
    Ui::Widget *ui;
    QFile file;
signals:
    void sig_log(QString S);//显示数据
    void sig_receivedCommand(QString S);//显示数据
};
#endif // WIDGET_H

.cpp文件:
#include "widget.h"
#include "ui_widget.h"
#include<iostream>
#include<windows.h>
#include<io.h>
#include<fcntl.h>
#include<QSocketNotifier>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("子进程");
 
    QFuture<void> fu=QtConcurrent::run(this,&Widget::readStdin);//开启一个线程
    connect(this,&Widget::sig_receivedCommand,this,[&](QString s)
    {
        ui->textEdit->append("父线程:"+s);
    });
    connect(this,&Widget::sig_log,this,[=](QString s)
    {
        ui->textEdit->append("父线程:"+s);
    });
 
}
 
Widget::~Widget()
{
    delete ui;
}
 
 
void Widget::readStdin()//读取数据
{
    bool ok=true;
    char chbuf[1024];//缓存
    DWORD dwRead;//32位无符号整数
    HANDLE hStdinDup;//HANDLE 句柄类型
 
    const HANDLE hStdin=GetStdHandle(STD_INPUT_HANDLE);//GetStdHandle获取标准输入的句柄
    if(hStdin==INVALID_HANDLE_VALUE)//为无效句柄的话
        return;
    DuplicateHandle(GetCurrentProcess(),hStdin,
                    GetCurrentProcess(),&hStdinDup,0,false,DUPLICATE_SAME_ACCESS);//创建一个新句柄
    CloseHandle(hStdin);//关闭旧句柄
    while(ok)
    {
        ok=ReadFile(hStdinDup,chbuf,sizeof(chbuf),&dwRead,NULL);//读取hstdinDup句柄文件中的数据
        emit sig_log(QLatin1String("ok is:")+QString::number(ok));
        if(ok &&dwRead!=0)
        {
            emit sig_receivedCommand(QString::fromUtf8(chbuf,dwRead));//读取数据
        }
    }
 
}
 
void Widget::on_pushButton_clicked()//发送数据
{
    if(ui->lineEdit->text().isEmpty())
    {
        QMessageBox::information(this,"提示信息","输入框不能为空。",QMessageBox::Ok);
        return;
    }
    QFile fileout;
    if(fileout.open(stdout,QIODevice::WriteOnly))
    {
        QString S=ui->lineEdit->text();
        fileout.write(S.toStdString().c_str());
        ui->textEdit->append("子线程:"+S);
        fileout.close();//关闭文件
    }
 
}


原文地址:https://blog.csdn.net/g200407331/article/details/140541334

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!