背景: 以下函數
1 bool Socket::getTcpInfo(struct tcp_info* tcpi) const 2 { 3 socklen_t len = sizeof(*tcpi); 4 memZero(tcpi, len); 5 return ::getsockopt(sockfd_, SOL_TCP, TCP_INFO, tcpi, &len) == 0; 6 }
有以下幾點不太明白:
1. struct tcp_info是個什么結構體
2. getsockopt這個函數的功能是什么
下面一一作答:
這個結構體里面包含的東西就多了,
1 struct tcp_info { 2 __u8 tcpi_state; //tcp state: TCP_SYN_SENT,TCP_SYN_RECV,TCP_FIN_WAIT1,TCP_CLOSE etc 3 __u8 tcpi_ca_state; //congestion state: 4 __u8 tcpi_retransmits; //重傳數,表示當前待重傳的包數,這個值在重傳完畢后清零 5 __u8 tcpi_probes; ///* 持續定時器或保活定時器發送且未確認的段數*/ 6 __u8 tcpi_backoff; //用來計算持續定時器的下一個設計值的指數退避算法指數,在傳送超時是會遞增。 7 __u8 tcpi_options; //tcp頭部選項是否包含:擴展因子、時間戳、MSS等內容 8 __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; //擴展因子數值 9 __u8 tcpi_delivery_rate_app_limited:1; //限速標志 10 11 __u32 tcpi_rto; //重傳超時時間,這個和RTT有關系,RTT越大,rto越大 12 __u32 tcpi_ato; //用來延時確認的估值,單位為微秒. 13 //在收到TCP報文時,會根據本次與上次接收的時間間隔來調整改制,在設置延遲確認定時器也會根據 14 //條件修改該值 15 __u32 tcpi_snd_mss; // 本端的MSS 16 __u32 tcpi_rcv_mss; // 對端的MSS 17 18 __u32 tcpi_unacked; //未確認的數據段數 19 __u32 tcpi_sacked; //2個含義:server端在listen階段,可以接收連接的數量;收到的SACK報文數量 20 __u32 tcpi_lost; //本端在發送出去被丟失的報文數。重傳完成后清零 21 __u32 tcpi_retrans; /* 重傳且未確認的數據段數 */ 22 __u32 tcpi_fackets; 23 24 /* Times. */ 25 __u32 tcpi_last_data_sent; //當前時間-最近一個包的發送時間,單位是毫秒 26 __u32 tcpi_last_ack_sent; /* 未使用*/ 27 __u32 tcpi_last_data_recv; //當前時間-最近接收數據包的時間,單位是毫秒 28 __u32 tcpi_last_ack_recv; //當前時間-最近接收ack的時間,單位是毫秒 29 30 /* Metrics. */ 31 __u32 tcpi_pmtu; /* 最后一次更新的路徑MTU */ 32 __u32 tcpi_rcv_ssthresh; //當前接收窗口的大小 33 __u32 tcpi_rtt; //smoothed round trip time,微妙 34 __u32 tcpi_rttvar; //描述RTT的平均偏差,該值越大,說明RTT抖動越大 35 __u32 tcpi_snd_ssthresh; //擁塞控制慢開始閾值 36 __u32 tcpi_snd_cwnd; //擁塞控制窗口大小 37 __u32 tcpi_advmss; //本端的MSS上限 38 __u32 tcpi_reordering; /* 沒有丟包時,可以重新排序的數據段數 */ 39 40 __u32 tcpi_rcv_rtt; // 作為接收端,測出的RTT值,單位為微秒. 這個值不是對方計算並傳送過來的rtt,而是作為接收端,在沒發送數據的情況下 41 // 通過接收發送端發送的數據的情況計算得到的rtt值。在數據發送方,如果不接受數據,這個值一般情況下為0。 42 __u32 tcpi_rcv_space; /* 當前接收緩存的大小 */ 43 44 __u32 tcpi_total_retrans; //統計總重傳的包數,持續增長。 45 46 __u64 tcpi_pacing_rate; //發送速率 47 __u64 tcpi_max_pacing_rate; //最大發送速率,默認是unlimited,可以通過SO_MAX_PACING_RATE來設置 48 __u64 tcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ 49 __u64 tcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ 50 __u32 tcpi_segs_out; /* RFC4898 tcpEStatsPerfSegsOut */ 51 __u32 tcpi_segs_in; /* RFC4898 tcpEStatsPerfSegsIn */ 52 53 __u32 tcpi_notsent_bytes; 54 __u32 tcpi_min_rtt; 55 __u32 tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */ 56 __u32 tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */ 57 58 __u64 tcpi_delivery_rate; 59 60 __u64 tcpi_busy_time; /* Time (usec) busy sending data */ 61 __u64 tcpi_rwnd_limited; /* Time (usec) limited by receive window */ 62 __u64 tcpi_sndbuf_limited; /* Time (usec) limited by send buffer */ 63 };
基本包含了所有的tcp鏈接中的信息。
getsockopt函數的功能就很簡單了 就是獲取tcp鏈接過程中的信息