006 打开文件和下载文件

怎么接收到命令,以及如何将结果返回给客户端在2、3、4节已经介绍清楚,本节只讨论功能实现

1 运行文件

逻辑步骤:

  • 获取运行的文件的路径

  • 调用ShellExecuteA运行文件

参考代码:

int RunFile()
{
    // 拿到路径
    std::string strFilePath;
    CServerSocket::getInstance()->GetFilePath(strFilePath);
    // ShellExecuteA 选用A是因为std::string 是多字节字符集的
    // 对指定文件执行操作。
    BYTE result = TRUE;
    // 执行文件失败
    if ((INT_PTR)ShellExecuteA(NULL, NULL, strFilePath.c_str(), NULL, NULL, SW_SHOWNORMAL) < 32)
    {
        result = FALSE;
        CPacket packet(2, &result, 1);
        CServerSocket::getInstance()->Send(packet);
        return -1;
    }
    // 执行完后返回一个数据包表示当前命令服务器接收并执行了
    CPacket packet(2, &result, 1);
    CServerSocket::getInstance()->Send(packet);
    return 0;
}

2 下载文件

下载文件的本质就是对方发送一个下载文件的路径(第五节回去文件和目录信息),我们拿到这个路径,对这个文件进行读取,我们可以先获取文件有多少字节,发送给客户端,让客户端那边有个进度,后面一次读取多少就发送给客户端,客户端发送命令后就等待接收数据。

逻辑步骤:

  • 获取文件路径

  • 获取文件长度

  • 不停的read,每read一次就发送一次read到的数据

参考代码:

int DownloadFile()
{
    // 获取要下载的文件路径
    std::string strFilePath;
    CServerSocket::getInstance()->GetFilePath(strFilePath);
    // 因为不知道对方要下载什么类型的文件所有以二进制的方式读取
    // 打开文件
    // 文件长度
    long long data = 0;
    FILE* pfile = fopen(strFilePath.c_str(), "rb");
    if (pfile == NULL)
    {
        CPacket packet(4, (BYTE*)&data, 8);
        CServerSocket::getInstance()->Send(packet);
        return -1;
    }
    // 获取文件长度
    // fseek 和 _fseeki64 函数将与 stream 关联的文件指针(如有)一起移动到新位置
    // SEEK_END:fseek将文件指针移到指定位置。SEEK_END 文件结尾
    // 0:SEEK_END 中的第几个字节
    fseek(pfile, 0, SEEK_END);
    // ftell 和 _ftelli64 函数检索与 stream 关联的文件指针(如果有)的当前位置。 位置表示为相对于流开头的偏移量。
    data = ftell(pfile);
    // 恢复文件指针在初始值
    fseek(pfile, 0, SEEK_SET);
    CPacket head(4, (BYTE*)&data, 8);
    CServerSocket::getInstance()->Send(head);
​
    // 读取发送文件数据
    char buffer[1024] = "";
    size_t rlen = 0;
    /*
    fread 函数最多从输入 stream 中读取 size 字节的 count 项并将它们存储在 buffer 中。 
    与 stream 关联的文件指针(如有)以 fread 读取的字节数推进。
    */
    do {
        // fread一次读1字节 一次总共最大读1024字节
        rlen = fread(buffer, 1, 1024, pfile);
        CPacket pack(4, (BYTE*)buffer, rlen);
        CServerSocket::getInstance()->Send(pack);
    } while (rlen > 0);
    // 关闭文件
    fclose(pfile);
    // 读取结束发一个空包,好给客户端一个结束接收的标志
    CPacket pack(4, NULL, 0);
    CServerSocket::getInstance()->Send(pack);
    return 0;
}
  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值