FastDFS客户端协议

/*
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;
}



你可能感兴趣的:(FastDFS)