在应用层获取tcp拥塞窗口信息

2019-06-24  本文已影响0人  help_youself

 可以在应用层通过tcp_info获取tcp的拥塞串口大小等信息,需要升级内核,过低的版本不支持这个结构体。能开启BBR拥塞控制的内核版本,就差不多。
例子tcp_info.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/tcp.h>  //struct tcp_info
static const size_t TCP_CC_NAME_MAX = 16;
void error_handling(char *message);
void print_cc_type(int fd){
    char optval[TCP_CC_NAME_MAX];
    memset(optval,0,TCP_CC_NAME_MAX);
    int length=sizeof(optval);
    getsockopt(fd,IPPROTO_TCP, TCP_CONGESTION, (void*)optval,(socklen_t*)&length);
    printf("cctype %s\n",optval);
}
void print_tcp_info(int fd){
    struct tcp_info info;
    int length=sizeof(struct tcp_info);
     if(getsockopt(fd,IPPROTO_TCP,TCP_INFO,(void*)&info,(socklen_t*)&length)==0){
        printf("cwnd %u ss %u\n",info.tcpi_snd_cwnd,info.tcpi_snd_ssthresh);
     }
}
int set_congestion_type(int fd,char *cc){
    char optval[TCP_CC_NAME_MAX];
    memset(optval,0,TCP_CC_NAME_MAX);
    strncpy(optval,cc,TCP_CC_NAME_MAX);
    int length=strlen(optval)+1;
    int rc=setsockopt(fd,IPPROTO_TCP, TCP_CONGESTION, (void*)optval,length);
    if(rc!=0){
        printf("cc is not supprt\n");
    }
    return rc;
}
int main(int argc, char* argv[])
{
    int sock;
    struct sockaddr_in serv_addr;
    char message[30];
    int str_len=0;
    int idx=0, read_len=0;
    const char *server_ip="127.0.0.1";
    uint16_t server_port=1234;
    char *cc_type="cubic";
    
    sock=socket(PF_INET, SOCK_STREAM, 0);
    if(sock == -1)
        error_handling("socket() error");

    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=inet_addr(server_ip);
    serv_addr.sin_port=htons(server_port);
    
    print_tcp_info(sock);
    set_congestion_type(sock,cc_type);
    print_cc_type(sock);
    /*if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) 
        error_handling("connect() error!");

    while(read_len=read(sock, &message[idx++], 1))
    {
        if(read_len==-1)
            error_handling("read() error!");

        str_len+=read_len;
    }

    printf("Message from server: %s \n", message);
    printf("Function read call count: %d \n", str_len);*/
    close(sock);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

 运行结果:

Reference:
TCP服务器/客户端实例(C/C++)
TCP_INFO信息查询
getsockopt的TCP层实现剖析
Logging TCP state variables such as Congestion Window from user space
使用标准方式在 Ubuntu 16.04 下启用 TCP 拥塞控制之 BBR

上一篇下一篇

猜你喜欢

热点阅读