2009-07-17 5 views
2

내 응용 프로그램 전송 속도를 900kbps로 제한하려하지만 사용하는 프로토콜이 메시지 지향이며 메시지 크기가 매우 다릅니다. 나는 40 바이트에서 최대 125000 바이트까지 메시지를 가질 수 있으며 모든 메시지는 원자 단위로 보내집니다.메시지 용 토큰 양동이 또는 새는 물통

토큰 버킷 버퍼를 구현하려고 시도했지만 낮은 버킷 크기를 설정하면 큰 패킷이 전송되지 않고 더 큰 버킷이 속도 제한이없는 큰 버스트가됩니다.

이 C에서 나의 작은 구현 : 그런 곳에서

typedef struct token_buffer { 
    size_t capacity; 
    size_t tokens; 
    double rate; 
    uint64_t timestamp; 

} token_buffer; 


static uint64_t time_now() 
{ 
    struct timeval ts; 
    gettimeofday(&ts, NULL); 
    return (uint64_t)(ts.tv_sec * 1000 + ts.tv_usec/1000); 
} 

static int token_buffer_init(token_buffer *tbf, size_t max_burst, double rate) 
{ 
    tbf->capacity = max_burst; 
    tbf->tokens = max_burst; 
    tbf->rate = rate; 
    tbf->timestamp = time_now(); 
} 

static size_t token_buffer_consume(token_buffer *tbf, size_t bytes) 
{ 
    // Update the tokens 
    uint64_t now = time_now(); 
    size_t delta = (size_t)(tbf->rate * (now - tbf->timestamp)); 
    tbf->tokens = (tbf->capacity < tbf->tokens+delta)?tbf->capacity:tbf->tokens+delta; 
    tbf->timestamp = now; 

    fprintf(stdout, "TOKENS %d bytes: %d\n", tbf->tokens, bytes); 

    if(bytes <= tbf->tokens) { 
    tbf->tokens -= bytes; 
    } else { 
    return -1; 
    } 

    return 0; 
} 

) (주 : 당신은 tbf-에 할당됩니다있는 (max_burst하여 최대 메시지 크기를 제한하고

while(1) { 
    len = read_msg(&msg, file); 

    // Loop until we have enough tokens. 
    // if len is larger than the bucket capacity the loop never ends. 
    // if the capacity is too large then no rate limit occurs. 
    while(token_buffer_consume(&tbf,msg, len) != 0) {} 

    send_to_net(&msg, len); 
} 

답변

2

> 용량) - tbf-> 토큰이이 값을 초과하여 증가하지 않으므로 더 큰 메시지는이 검사로 인해 절대로 전송되지 않습니다.

if(bytes <= tbf->tokens) { 
    tbf->tokens -= bytes; 
    } else { 
    return -1; 
    } 

코드는 실제로 버스트에 대한 하드 제한을 max_burst로 설정합니다. 따라서이 버스트 크기를 원한다면 메시지를 조각 내야합니다. 에

if(tbf->tokens > 0) { 
    tbf->tokens -= bytes; 
} else { 
    return -1; 
} 

의미 론적 약간 다를 수 있지만 :

이 당신이 리미터를 삽입 할 수있는 코드에서 유일한 장소입니다 가정 할 때, 당신은 당신이 위의 조각을 교체하면 더 좋은 결과를 얻을 수 있습니다 오랜 기간 동안의 평균치로 당신이 찾고자하는 속도와 대략 일치해야합니다. 물론 1Gbps 링크를 통해 하나의 메시지로 125K를 보내는 경우 900kbps 속도에 대해 거의 이야기 할 수 없습니다. 전체 1Gbps 패킷 버스트가되며 더 낮은 속도의 링크가있는 경우 어딘가에 대기해야합니다. 이 경우 일부 패킷을 잃을 준비를하십시오.

그러나 사용중인 응용 프로그램과 전송 네트워크 프로토콜 (TCP/UDP/SCTP/...?)에 따라 모양 코드를 스택 아래로 옮길 수도 있습니다. 일반적으로 네트워크상의 패킷은 어쨌든 최대 1500 바이트 만 (다양한 네트워크/전송 프로토콜 헤더 포함)

테스팅 용으로 흥미로운 점은 http://www.linuxfoundation.org/en/Net:Netem입니다. 목표가 소용량 링크를 처리하려고하는 경우입니다. 또는 1mbps 직렬 포트가 연결된 이전 라우터 몇 대를 연속적으로 연결하십시오.