forked from StevenBaby/onix
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
61f7365
commit e3a229e
Showing
12 changed files
with
333 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# TCP 超时重传 | ||
|
||
## 重传超时 | ||
|
||
TCP 超时和重传的基础是怎样根据给定连接的 往返时间 RTT(Round Trip Time) 设置 RTO (Retransmission TimeOut)重传超时,以取的对特定连接比较合理的重传时间。 | ||
|
||
### 关键术语 | ||
|
||
- RTT: Round Trip Time 往返时间 | ||
- SRTT: Smoothed RTT 平滑的往返时间,(加权平均值) | ||
- RTO: Retransmission TimeOut 重传超时 | ||
- RTTVAR: RTT 的残差(估计值) | ||
|
||
### 经典方法 | ||
|
||
$$ | ||
\text{SRTT} = \alpha(\text{SRTT}) + (1 - \alpha)(\text{RTT}) | ||
$$ | ||
|
||
每次有新的 RTT 时,需要更新 SRTT,其中 $\alpha \in [0.8, 0.9]$,这种方法叫做指数加权移动平均 (Exponentially Weighted Moving Average EWMA),或者 低通滤波器(Low-Pass Filter),实现起来比较简单; | ||
|
||
RFC793 推荐如下公式计算 RTO: | ||
|
||
$$ | ||
\text{RTO} = \min(\text{ubound}, \max(\text{lbound}, \beta(\text{SRTT}))) | ||
$$ | ||
|
||
- lbound:RTO 下界,最小值; | ||
- ubound:RTO 上界,最大值; | ||
- $\beta$:时延离散因子,推荐值 1.3 ~ 2.0 (可以理解为 RTT 的方差); | ||
|
||
### 标准方法 | ||
|
||
标准方法定义在 RFC6298; | ||
|
||
$$ | ||
\begin{aligned} | ||
\text{SRTT} &= (1 - g)(\text{SRTT}) + g(\text{RTT}) \\ | ||
\text{RTTVAR} &= (1 - h)(\text{RTTVAR}) + h(|\text{RTT} - \text{SRTT}|) \\ | ||
\text{RTO} &= \text{SRTT} + 4(\text{RTTVAR}) | ||
\end{aligned} | ||
$$ | ||
|
||
经过简单的计算,可以的到如下的公式,更容易用于程序设计; | ||
|
||
$$ | ||
\begin{aligned} | ||
E &= \text{RTT} - \text{SRTT} \\ | ||
\text{SRTT} &= \text{SRTT} + gE \\ | ||
\text{RTTVAR} &= \text{RTTVAR} + h(|E| - \text{RTTVAR}) \\ | ||
\text{RTO} &= \text{SRTT} + 4(\text{RTTVAR}) | ||
\end{aligned} | ||
$$ | ||
|
||
其中 $\displaystyle g = {1 \over 8}$,$\displaystyle h = {1 \over 4}$; | ||
|
||
## 指数退避 | ||
|
||
每次重传间隔时间加倍称为二进制指数退避(binary exponential backoff); | ||
|
||
## 参考 | ||
|
||
- TCP/IP 详解 卷1:协议 | ||
- TCP/IP 详解 卷2:实现 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
#include <onix/types.h> | ||
#include <onix/stdio.h> | ||
#include <onix/syscall.h> | ||
#include <onix/string.h> | ||
#include <onix/fs.h> | ||
#include <onix/net.h> | ||
|
||
#define BUFLEN 4096 | ||
|
||
static char tx_buf[BUFLEN]; | ||
static char rx_buf[BUFLEN]; | ||
|
||
int main(int argc, char const *argv[]) | ||
{ | ||
sockaddr_in_t addr; | ||
|
||
int fd = socket(AF_INET, SOCK_STREAM, PROTO_TCP); | ||
if (fd < EOK) | ||
{ | ||
printf("create client socket failure...\n"); | ||
return fd; | ||
} | ||
|
||
inet_aton("192.168.111.33", addr.addr); | ||
addr.family = AF_INET; | ||
addr.port = htons((u16)time()); | ||
|
||
int ret = bind(fd, (sockaddr_t *)&addr, sizeof(sockaddr_in_t)); | ||
printf("socket bind %d\n", ret); | ||
if (ret < EOK) | ||
goto rollback; | ||
|
||
int val = 1; | ||
ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, 4); | ||
printf("socket keepalive %d\n", ret); | ||
if (ret < EOK) | ||
goto rollback; | ||
|
||
val = 1; | ||
ret = setsockopt(fd, SOL_SOCKET, SO_TCP_NODELAY, &val, 4); | ||
printf("socket nodelay %d\n", ret); | ||
if (ret < EOK) | ||
goto rollback; | ||
|
||
inet_aton("192.168.111.1", addr.addr); | ||
addr.family = AF_INET; | ||
addr.port = htons(7777); | ||
ret = connect(fd, (sockaddr_t *)&addr, sizeof(sockaddr_in_t)); | ||
printf("socket connect %d\n", ret); | ||
|
||
memset(tx_buf, 'A', sizeof(tx_buf)); | ||
|
||
u32 send_timing = time(); | ||
u32 recv_timing = time(); | ||
u32 send_count = 0; | ||
u32 recv_count = 0; | ||
|
||
pid_t pid = fork(); | ||
|
||
while (true) | ||
{ | ||
if (pid) | ||
{ | ||
send_count++; | ||
ret = send(fd, tx_buf, sizeof(tx_buf), 0); | ||
// printf("message sent %d...\n", ret); | ||
if (ret < EOK) | ||
goto rollback; | ||
|
||
u32 now = time(); | ||
int offset = now - send_timing; | ||
send_timing = now; | ||
if (offset > 0) | ||
{ | ||
printf("send speed: %dKB/s\n", send_count * 4 / offset); | ||
send_count = 0; | ||
} | ||
} | ||
else | ||
{ | ||
recv_count++; | ||
ret = recv(fd, rx_buf, BUFLEN, 0); | ||
// printf("message recv %d...\n", ret); | ||
if (ret < EOK) | ||
goto rollback; | ||
|
||
u32 now = time(); | ||
int offset = now - recv_timing; | ||
recv_timing = now; | ||
if (offset > 0) | ||
{ | ||
printf("recv speed: %dKB/s\n", recv_count * 4 / offset); | ||
recv_count = 0; | ||
} | ||
} | ||
} | ||
|
||
rollback: | ||
if (fd > 0) | ||
close(fd); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.