0

「ヘッダーの作成方法」を教えてもらえますか? 私は FTP クライアント サーバー コードを書いています。そして、データのサイズなどの情報とともにサーバーに送信する必要があるすべてのデータパケットに対して、クライアント側でヘッダーを追加したいと考えています。

私はSOでいくつかの例を見てきましたが、正確な方法を理解することはできません. サンプル/サンプル コードへのポインタをいただければ幸いです。

4

3 に答える 3

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);
}

「アサート」ステートメントは、プログラムが正しく記述されている場合、つまりポインターが有効である場合に常に真になることをテストします。どの関数もtrue、成功したfalse場合と失敗した場合に戻ります。

ソケットには標準の POSIX 関数を使用しました。これは、WinSock がこれらを実装しており、かなり移植性があるためです。

あなたの宿題は、含める必要があるヘッダーを見つけることですPRIu64:)

于 2012-03-01T12:02:12.117 に答える
1

パケットを構築するためのライブラリである scapy を調べてください。必要なものだと思います。

于 2012-03-01T11:37:30.490 に答える
0

両方のクライアントサーバーのヘッダーに含めるメンバーを使用して構造体を定義します(両方の構造体にヘッダーファイルを含めることをお勧めします)。元のメッセージの前にヘッダーを送信します。構造体の固定長のパラメーターを持つサーバーでのrecv。

typedef struct  
{
    DWORD   dwMsgType ; 
    DWORD   dwMsgSize ;
}MSG_HEADER, *PMSG_HEADER ;
于 2012-03-02T12:53:00.530 に答える