FastDFS客户端协议

来源:互联网 发布:打电话不要钱的软件 编辑:程序博客网 时间:2024/05/01 04:09
/*
FastDFS 作者提供的客户端API都是阻塞式,现在高并发高性能的程序一般都是非阻塞的处理模式,
这里根据FastDFS协议封装读、写、删除、查询几个API。
*/

//需要包含FastDFS以下几个头文件

#include "common_define.h"
#include "tracker_proto.h"
#include "fdfs_global.h"
#include "sockopt.h"
#include "fdfs_client.h"

//这是客户端API的一个宏,原样搬过来,用来分解组名和文件名
#define DFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id) \
char new_file_id[FDFS_GROUP_NAME_MAX_LEN + 128]; \
char *group_name; \
char *filename; \
char *pSeperator; \
\
snprintf(new_file_id, sizeof(new_file_id), "%s", file_id); \
pSeperator = strchr(new_file_id, FDFS_FILE_ID_SEPERATOR); \
if (pSeperator == NULL) \
{ \
return EINVAL; \
} \
\
*pSeperator = '\0'; \
group_name = new_file_id; \
filename =  pSeperator + 1; \

/*
描述:发送上传文件的协议, 在上传文件内容时,先要调用些函数,把协议数据发送给storage server
参数:
    file_size: 上传文件的大小
    ext_name:  文件的扩展名, 可以为空
    file_type: 文件类型, 0 为普通文件, 1为可追加或修改的文件
*/

int upload_file_proto(const long long      file_size,
                      const std::string    ext_name, 
                      const int            file_type)
{
    char out_buff[512];
    char* p = out_buff;
    int store_path_index = -1;
    TrackerHeader* pHeader = (TrackerHeader *)out_buff;

    memset(out_buff, 0x00, sizeof(out_buff));

    p = out_buff + sizeof(TrackerHeader);
    *p++ = (char)store_path_index;

    long2buff(file_size, p);
    p += FDFS_PROTO_PKG_LEN_SIZE;

    memset(p, 0x00, FDFS_FILE_EXT_NAME_MAX_LEN);
    if(!ext_name.empty())
    {
        int file_ext_len = ext_name.size();
        if (file_ext_len > FDFS_FILE_EXT_NAME_MAX_LEN)
        {
            file_ext_len = FDFS_FILE_EXT_NAME_MAX_LEN;
        }
        memcpy(p, ext_name.c_str(), file_ext_len);
    }
    p += FDFS_FILE_EXT_NAME_MAX_LEN;

    long2buff((p - out_buff) + file_size - sizeof(TrackerHeader), pHeader->pkg_len);
    pHeader->status = 0;
    pHeader->cmd = STORAGE_PROTO_CMD_UPLOAD_FILE;
    if(1 == file_type)
    {
        pHeader->cmd = STORAGE_PROTO_CMD_UPLOAD_APPENDER_FILE;
    }

    //发送消息到storage server
    int iRet = send_header_to_fdfs(out_buff, p - out_buff);
    if(0 > iRet)
    {
        return iRet;
    }

    return 0;
}


/*
描述:从FastDFS下载文件的协议, 在下载文件内容时,先要调用些函数,把协议数据发送给storage server
参数:
    file_id: 文件ID, 些ID为文件上传后FastDFS返回的文件ID
    read_len:   读的长度, 为0则读整个文件
    offset:     文件的偏移,如果重头开始读,则为0
*/

int read_file_proto(const std::string & file_id, const long long read_len, const long long file_offset)
{
    DFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id.c_str())

    TrackerHeader *pHeader = NULL;
    char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + 128];
    char *p = NULL;
     int out_bytes;
     int filename_len;

    memset(out_buff, 0, sizeof(out_buff));
    pHeader = (TrackerHeader *)out_buff;
    p = out_buff + sizeof(TrackerHeader);

    long2buff(file_offset, p);
    p += 8;

    long2buff(read_len, p);
    p += 8;

    snprintf(p, sizeof(out_buff) - (p - out_buff), "%s", group_name);
    p += FDFS_GROUP_NAME_MAX_LEN;

    filename_len = snprintf(p, sizeof(out_buff) - (p - out_buff), 
    "%s", filename);
    p += filename_len;

    out_bytes = p - out_buff;
    long2buff(out_bytes - sizeof(TrackerHeader), pHeader->pkg_len);

    pHeader->cmd = STORAGE_PROTO_CMD_DOWNLOAD_FILE;

    //发送消息到storage server
    int iRet = send_header_to_fdfs(out_buff, p - out_buff);
    if(0 > iRet)
    {
        return iRet;
    }


    return 0;
}


/*
描述:从FastDFS删除文件的协议, 删除一个文件时要调用此函数,把协议数据发送给storage server
参数:
    file_id: 文件ID, 些ID为文件上传后FastDFS返回的文件ID
*/

int delete_file_proto(const std::string & file_id)
{
    DFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id.c_str())

    char out_buff[sizeof(TrackerHeader)+ FDFS_GROUP_NAME_MAX_LEN + 128];

    memset(out_buff, 0, sizeof(out_buff));
    snprintf(out_buff + sizeof(TrackerHeader), 
        sizeof(out_buff) - sizeof(TrackerHeader),  
        "%s", 
        group_name);

    int filename_len = snprintf(out_buff + sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN, 
    sizeof(out_buff) - sizeof(TrackerHeader) - FDFS_GROUP_NAME_MAX_LEN,  
        "%s", 
        filename);

    TrackerHeader* pHeader = (TrackerHeader *)out_buff;
    long2buff(FDFS_GROUP_NAME_MAX_LEN + filename_len, pHeader->pkg_len);
    pHeader->cmd = STORAGE_PROTO_CMD_DELETE_FILE;

    //发送消息到storage server
    int iRet = send_header_to_fdfs(out_buff, p - out_buff);
    if(0 > iRet)
    {
        return iRet;
    }

    return 0;
}


/*
描述:从FastDFS查询文件信息的协议
参数:
    file_id: 文件ID, 些ID为文件上传后FastDFS返回的文件ID
*/

int query_file_infor_proto(const std::string & file_id)
{
    DFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id.c_str())


    TrackerHeader *pHeader;
    char out_buff[sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN + 128];
    int filename_len;

    memset(out_buff, 0x00, sizeof(out_buff));

    pHeader = (TrackerHeader *)out_buff;
    snprintf(out_buff + sizeof(TrackerHeader), sizeof(out_buff) - sizeof(TrackerHeader),  
        "%s", group_name);

    filename_len = snprintf(out_buff + sizeof(TrackerHeader) + FDFS_GROUP_NAME_MAX_LEN, 
    sizeof(out_buff) - sizeof(TrackerHeader) - FDFS_GROUP_NAME_MAX_LEN,  
        "%s", 
        filename);

    long2buff(FDFS_GROUP_NAME_MAX_LEN + filename_len, pHeader->pkg_len);
    pHeader->cmd = STORAGE_PROTO_CMD_QUERY_FILE_INFO;
    pHeader->status = 0;

    //发送消息到storage server

    int iRet = send_header_to_fdfs(out_buff, p - out_buff);
    if(0 > iRet)
    {
        return iRet;
    }

    return 0;
}




/*
描述:修改一个存储在FastDFS的文件内容的协议, 
参数:
    file_buf:    要修改的文件内容缓冲区
    file_len:    要修改的文件内容的长度
    file_offset: 要修改文件的偏移
    file_id:     要修改文件的文件ID, 些ID为文件上传后FastDFS返回的文件ID
*/

int modify_file_proto(const char*       file_buf, 
                    const long long     file_len, 
                    const long long     file_offset,
                    const std::string & file_id)
{
    DFS_SPLIT_GROUP_NAME_AND_FILENAME(file_id.c_str());


    TrackerHeader *pHeader;
    char out_buff[512];
    char *p;
    int appender_filename_len = strlen(filename);

    memset(out_buff, 0x00, sizeof(out_buff));

    pHeader = (TrackerHeader *)out_buff;
    p = out_buff + sizeof(TrackerHeader);
    long2buff(appender_filename_len, p);
    p += FDFS_PROTO_PKG_LEN_SIZE;

    long2buff(file_offset, p);
    p += FDFS_PROTO_PKG_LEN_SIZE;

     long2buff(file_len, p);
     p += FDFS_PROTO_PKG_LEN_SIZE;

     memcpy(p, filename, appender_filename_len);
     p += appender_filename_len;

     long2buff((p - out_buff) + file_len - sizeof(TrackerHeader), pHeader->pkg_len);
     pHeader->cmd = STORAGE_PROTO_CMD_MODIFY_FILE;
     pHeader->status = 0;

    //发送消息到storage server
    int iRet = send_header_to_fdfs(out_buff, p - out_buff);
    if(0 > iRet)
    {
        return iRet;
    }

    //发送消息到storage server
    iRet = send_header_to_fdfs(file_buf, file_len);
    if(0 > iRet)
    {
        return iRet;
    }

    return 0;
}



1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 四个月宝宝没抱住摔了头部怎么办 老公老是跟年轻的小姑娘聊天怎么办 老婆出轨老公想离婚又舍不得怎么办 孕妇打完无痛分娩针就想睡觉怎么办 熟食店开空调菜品吹的很干怎么办 不锈钢锅在液化气烧了发黄怎么办 在小镇门面卤菜店不好卖怎么办? 被辣椒辣到嘴唇了该怎么办 沁园净水机不制水指示灯不亮怎么办 太辣了辣得胃疼怎么办 出现连接问题或mmi码无效怎么办 存折丢了怎么办卡号也不记得了 车内皮子被烂苹果腐蚀有印怎么办 锅被腐蚀后变黑色应该怎么办 后厨炉灶里的炉芯进水了怎么办 小儿九个月老是流黄鼻子该怎么办 肉炖的老了不烂怎么办 吃了凉东西现在一直打嗝应该怎么办 喝了很多水还是觉得口渴怎么办 刚买的猪肝没洗直接炒了怎么办 四个多月的宝宝吃了脏东西怎么办 狗吃了脏东西拉稀呕吐怎么办 五个月宝宝怕吃药导致奶不喝怎么办 蒸锅锅盖吸住了怎么办锅比锅盖要大 豇豆没熟孕妇吃了中毒怎么办 孩子积食拉不出粑粑憋的直哭怎么办 2岁宝宝总是半夜拉粑粑怎么办 金毛拉很臭的稀粑粑怎么办 点餐系统登录后没有菜单怎么办? 环亚在线微交易亏了钱怎么办 钢管舞报了教练班觉得学不会怎么办 微信上聊天被外国人给骗了该怎么办 微信冒充朋友骗走我钱怎么办 凉皮调料水鸡精味精放多了怎么办 吃了地屈孕酮后月经不干不净怎么办 藕片用热水炒后变色了怎么办? 外汇延期收款忘了报告了怎么办 怀孕不小心吃了马生菜怎么办 高压锅的皮圈很容易坏是怎么办 华为应用市场账号密码忘记了怎么办 业主对我们提出批评意见时怎么办