添加自定义邮件标头

时间:2012-03-01 11:32:57

标签: c++ windows sockets header ftp-client

任何人都可以告诉我:“如何构建标题?”我正在编写FTP客户端 - 服务器代码。我想在客户端为我必须发送到服务器的所有数据包添加一个Header,其中包含我的数据大小等信息。

我在SO看到了一些例子但是无法弄清楚确切的方法。 任何指向示例/示例代码的指针都将受到赞赏。

3 个答案:

答案 0 :(得分:1)

查看scapy,一个用于构建数据包的库。我认为这就是你所需要的。

答案 1 :(得分:1)

构建协议数据的最佳方法是在某处拥有uint8_t的缓冲区,并按照协议中的规定填充它。

对于FTP,这很简单,因为控制连接中只有ASCII字符串。这样的事情可能有用:

bool append_literal(uint8_t **cursor, uint8_t *end, uint8_t const *data, size_t size) {
    assert(cursor);
    assert(*cursor);
    assert(end);
    assert(*cursor < end);
    assert(data);
    if((end - *cursor) < size)    // Check buffer limit
        return false;
    memcpy(*cursor, data, size);  // Copy
    *cursor += size;              // Increment cursor
    return true;
}

bool append_number(uint8_t **cursor, uint8_t *end, uint64_t number) {
    assert(cursor);
    assert(*cursor);
    assert(end);
    assert(*cursor < end);
    if((end - *cursor) < 17)     // Max number of base 10 digits in uint64_t
        return false;
    *cursor += sprintf(*cursor, "%" PRIu64, number);
    return true;
}

bool append_uint32_binary(uint8_t **cursor, uint8_t *end, uint32_t value) {
    assert(cursor);
    assert(*cursor);
    assert(end);
    assert(*cursor < end);
    if((end - *cursor) < 4)      // Bytes needed for uint32 value
        return false;
    *(*cursor)++ = (value >> 24) & 0xff;
    *(*cursor)++ = (value >> 16) & 0xff;
    *(*cursor)++ = (value >> 8) & 0xff;
    *(*cursor)++ = value & 0xff;
    return true;
}

// Specific FTP commands
bool append_size_command(uint8_t **cursor, uint8_t *end, uint64_t size) {
    return append_literal(cursor, end, "SIZE ", 5) &&
        append_number(cursor, end, size) &&
        append_literal(cursor, end, "\r\n", 2);
}
// [...]

bool send_size_command(int fd, uint64_t size) {
    uint8_t buffer[32];
    uint8_t *cursor = buffer;
    uint8_t *const end = buffer + sizeof buffer;
    if(!append_size_command(&cursor, end, size))
        return false;
    size_t length = cursor - buffer;
    ssize_t sent = send(fd, buffer, length, 0);
    return (sent == length);
}

“assert”语句测试在程序正确编写时总是为真的事情,即指针有效。任何函数在成功时返回true,如果失败则返回false

我已经为套接字使用了标准POSIX函数,因为WinSock实现了这些函数,并且它们相当便携。

您的作业是查找PRIu64所需要包含的标题:)

答案 2 :(得分:0)

定义一个结构,其中包含您希望在Client-Server的Header中的成员(最好包含一个包含结构的Header文件)。在原始邮件之前发送标题。在服务器上使用固定长度的struct的参数进行recv。

typedef struct  
{
    DWORD   dwMsgType ; 
    DWORD   dwMsgSize ;
}MSG_HEADER, *PMSG_HEADER ;