Qt生产消费者模式应用--基于QSsh实现类似Xftp功能

10 篇文章 0 订阅
2 篇文章 0 订阅

一、记录起因:

在项目中遇到需要访问并展示远程文件,下载文件,获取远程路径的需求,类似xftp的功能,通过收集资料起初选择了使
用QFTP实现功能,最终也实现了基本的功能,但是QFTP的功能还是比较局限,比如删除非空文件夹的功能,虽然我通过
一系列骚操作瞎搞,也实现了删除非空文件夹的功能,但还是有BUG,经常删不干净,也不想去看了(异步删除文件夹,
循环遍历,真不是那么简单,逛了各种论坛,几乎没看到有解决的,甚至直接跳过了),不稳定且功能不够强大这可能也
是QFtp被弃用的原因吧,后面想到通过ssh协议实现,于是搞了个QSSH来实现了功能。

二、QSSh下载编译

参考网上大佬的吧,有编译好的,且实现了简单shell脚本的功能,在此感谢大佬。

三、利用SSh协议实现类似XFtp功能

1.原理

	大致思路就是通过发送shell命令,通过返回的消息格式解析特定的消息,获得相应参数更新界面,比如,我要实现文
	件预览功能,我可以发送个"ls -l"命令,获取到当前路径下的文件信息,然后解析数据,得到文件相关数据,更新到
	QTableView,我想获取当前路径可以发送“pwd”,想进入下一个目录可以用“cd”,如此实现。

2.生产消费者模式的应用

1.为什么要使用这种模式:
比如在进入一个远程路径时,我们需要通过pwd命令获取当前路径,需要ls命令获取,那就涉及到会连续发送多个命令,
连续发送多个命令收到多个回复,首先你并不知道哪个回复是对应你发送的那个命令,然后回复的格式并不是,你发一
句它回一句,可能是拼接的,诸如此类问题,所以实现的方式应该是发一条命令,解析一次回复并更新界面信息,完成后再发命令
再解析,为此可以采用生产者消费者模式,即我生产一堆命令,但是并不立即发送,而是存入数据结构,等待生产者告
知消费者当前命令已经处理完毕后,消费者再取出一条命令发出去。
2.我所采用的生成消费者模式图:

在这里插入图片描述
3.设计简要概述:
其实看图片已经很清晰了,就是主线程作为生产者,生产shell命令并加入队列,同时监控shell状态,当处理完一条返回消息时告知消费者线程当前shell状态,消费者线程在收到shell空闲时就会获取可用资源(如果没有就等待),获取当资源后就取出队列的第一个命令,发出shell命令后,shell进入忙碌状态,并释放一个空闲资源,如此,待当前命令处理完成之后,又生产者告知消费线程shell进入空闲,消费线程继续获取资源而后发送命令,直到所有命令处理完毕。
4.代码描述:
(1)生产者命令入列:

void FtpWidget::sendShellCommand(QString command)
{
    freeBytes.acquire();    //获得一个空闲缓冲区资源
    sshSendMsgQueue.enqueue(command);   //命令入列
    usedBytes.release();    //释放一个可使用的资源
}

(2)消费线程获取资源发送命令

void sshMsgSendThread::run()
{
    while(!stopped)
    {
        if(shellIsFree)
        {
            usedBytes.acquire(); //获取一个可使用的资源,没有资源时等待
            QString msg= sshSendMsgQueue.takeFirst();
            m_pShell->sshSendCmd(msg); //1.发送获得的shell命令
            emit SignalSshSendMsg(msg); //2.告知生产者当前发送的命令
            shellIsFree = false;    //3.shell进入忙碌状态
            freeBytes.release();    //释放一个空闲缓冲区资源
        }
    }
    stopped=false;
}
5.一些细节问题记录
(1)shh发送命令时,会有类似“[1;34]”这种类型的数据,这是颜色显示相关的,比如发送的ls命令查看当前路径文件,
在xshell中会以不同的颜色展示文件,文件夹等,颜色就是靠这个定义的,如果不想显示颜色,可以在结尾加“--
color=never”, 比如我获取列表的ls命令是“ls -lh -F --time-style '+%Y/%m/%d %H:%M:%S' --color=never\n”,这条命令
获取的信息就比较齐全了。
(2)ssh具备SftpChannel用来下载和上传文件,但是我没找到比较齐全的功能(比如进度获取啊,其他之类的),所以
我还是用ftp去上传下载的。
(3)在重命名文件时,由于打开了model的可编辑状态,导致每次想进入下一个目录(双击table)时如果点击第一列(只
允许编辑第一列)都会触发当前item进入编辑状态,而我只想通过右键编辑并不想保留双击编辑,不知道有没有属性可
以屏蔽双击编辑,但又能手动调用edit进行编辑,最终我的做法是定义一个状态标志,默认为false,model在设置编辑状
态时先判断状态标志为true时才允许编辑,于是我设置默认状态都不可编辑,在调用edit前设置变量为true,然后编辑完
成之后再设为false,以实现功能。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值