005 获取文件和目录信息

1 服务器运行逻辑

在前面几节中我们以及完成了数据包的收取(解析数据),数据包的发送(数据包的封包发送)

现在服务器逻辑如下:根据接收到命令号做出对应的处理,在对应的处理函数里把结果直接发送给客户端

CServerSocket* pserver = CServerSocket::getInstance();
            int acceptCount = 0;
            if (pserver->InitSocket() == false)
            {
                MessageBox(NULL, _T("网络初始化失败,请检查网络状态"), _T("网络初始化失败!!"), MB_OK | MB_ICONERROR);
                exit(0);
            }
            while (CServerSocket::getInstance() != NULL)
            {
                if (pserver->AcceptClient() == false)
                {
                    MessageBox(NULL, _T("接入用户失败,自动重试"), _T("接入用户失败!!"), MB_OK | MB_ICONERROR);
                    acceptCount += 1;
                    if (acceptCount >= 3)
                    {
                        MessageBox(NULL, _T("多次用户失败,退出程序"), _T("多次接入用户失败!!"), MB_OK | MB_ICONERROR);
                        exit(0);
                    }
                }
                // 接收数据,返回命令号,接收到的数据存放在m_packet成员变量里面
                int cmd = pserver->DealCommand();
                switch (cmd)
                {
                case 1:// 获取磁盘分区
                    MakeDriverInfo();
                    break;
                case 2:// 获取指定目录下的文件信息
                    MakeDirectoryInfo();
                    break;
                }
            }

2 获取文件和目录信息功能实现步骤

2.1 功能实现

首先服务器接收到获取文件和目录命令,从里面解析出数据,解析出获取哪个目录下的文件和目录

新增接口,返回路径信息

// 从包里面取出路径信息
    bool GetFilePath(std::string& strPath)
    {
        if ((m_packet.sCmd >= 2) && (m_packet.sCmd <= 4))
        {
            strPath = m_packet.strData;
            return true;
        }
        return false;
    }
  • 获取目录信息

  • 切换目录,判断是否有权限进入目录,或者是否是空的目录

  • 找到目录下的第一个文件

  • 找到一个就发送一个

  • 通过第一个文件继续找其它文件

2.2 参考代码:

在本代码中采用的是找到一个文件或文件夹就直接发送给客户端,如果等全部找到再发送,会导致客户端半天没有回馈

int MakeDirectoryInfo()
{
    // 获取目录
    std::string strFilePath;
    if (!CServerSocket::getInstance()->GetFilePath(strFilePath))
    {
        OutputDebugString(_T("当前的命令不是获取文件列表,命令解析错误"));
        return -1;
    }
    // 切换目录,判断是否有权限进入目录,或者是否是空的目录
    if (_chdir(strFilePath.c_str()) != 0)
    {
        FILEINFO finfo;
        finfo.IsInvalid = true;
        finfo.HasNext = false;
        finfo.isDirectory = true;
        memcpy(finfo.szName, strFilePath.c_str(), strFilePath.size());
        CPacket packet(2, (BYTE*)&finfo, sizeof(finfo));
        CServerSocket::getInstance()->Send(packet);
​
        OutputDebugString(_T("没有权限访问该目录"));
        return -2;
    }
    //遍历目录下的文件和文件夹
    // 先找到第一个文件,要准备一个信息缓冲区 fdata
    // _findfirst 返回标识与 filespec 规范匹配的文件或文件组的唯一搜索句柄
    // 可在后续调用 _findnext 或 _findclose 时使用
    _finddata_t fdata;
    int hfind = 0;
    if (hfind = (_findfirst("*", &fdata)) == -1)
    {
        OutputDebugString(_T("该目录下没有任何文件"));
        return -3;
    }
    // 查找与以前 _findfirst 调用中的 filespec 参数相匹配的下一个名称(如有),然后相应更改 fileinfo 结构内容。
    // 获取到文件信息后需要发送给对方,这个时候需要将文件信息封装一下 -- 定义结构体保存文件信息
    do {
        FILEINFO finfo;
        finfo.isDirectory = true;
        memcpy(finfo.szName, fdata.name, strlen(fdata.name));
        CPacket packet(2, (BYTE*)&finfo, sizeof(finfo));
        CServerSocket::getInstance()->Send(packet);
    } while (!_findnext(hfind, &fdata));
    // 文件目录发送完毕给客户端返回一个空包,客户端好判断是否接收完毕
    FILEINFO finfo;
    finfo.HasNext = false;
    CPacket packet(2, (BYTE*)&finfo, sizeof(finfo));
    CServerSocket::getInstance()->Send(packet);
    return 0;
}

2.2 文件信息的封装

由于对方想要的是文件信息,那么应该包含以下信息

  • 文件名

  • 是文件还是目录

  • 是否有效

  • 是否还有后续(用于接收方方便判断数据何时接收完毕)

所以我们需要把这些信息整合在一起,从而用到结构体,由于在c++里面类和结构体几乎一致,所以可以使用构造函数方便我们创建这个结构式简化赋值操作

代码如下:

typedef struct file_info
{
    // 使用构造函数方便初始值赋值,不然创建一个对象每一个都得手动赋值
    file_info()
    {
        IsInvalid = false;
        isDirectory = -1;
        HasNext = true;
        memset(szName, 0, sizeof(szName));
    } 
    // 是否无效 true无效,false有效,默认有效
    bool IsInvalid; 
    // 是否是目录,true目录,false文件,默认不是目录
    bool isDirectory;
    // 文件名
    char szName[256];
    // 是否还有后续,false没有,true有,默认还有
    bool HasNext;
}FILEINFO, *PFILEINFO;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值