# Conflicts:
#	README.md
This commit is contained in:
skywind3000 2017-06-08 00:07:25 +08:00
commit c129925f64
3 changed files with 47 additions and 47 deletions

4
ikcp.c
View File

@ -551,7 +551,7 @@ static void ikcp_update_ack(ikcpcb *kcp, IINT32 rtt)
kcp->rx_srtt = (7 * kcp->rx_srtt + rtt) / 8;
if (kcp->rx_srtt < 1) kcp->rx_srtt = 1;
}
rto = kcp->rx_srtt + _imax_(1, 4 * kcp->rx_rttval);
rto = kcp->rx_srtt + _imax_(kcp->interval, 4 * kcp->rx_rttval);
kcp->rx_rto = _ibound_(kcp->rx_minrto, rto, IKCP_RTO_MAX);
}
@ -749,7 +749,7 @@ int ikcp_input(ikcpcb *kcp, const char *data, long size)
ikcp_log(kcp, IKCP_LOG_INPUT, "[RI] %d bytes", size);
}
if (data == NULL || size < 24) return -1;
if (data == NULL || size < IKCP_OVERHEAD) return -1;
while (1) {
IUINT32 ts, sn, len, una, conv;

View File

@ -1,8 +1,8 @@
//=====================================================================
//
// test.cpp - kcp 测试用例
// test.cpp - kcp 测试用例
//
// 说明:
// 说明:
// gcc test.cpp -o test -lstdc++
//
//=====================================================================
@ -14,10 +14,10 @@
#include "ikcp.c"
// 模拟网络
// 模拟网络
LatencySimulator *vnet;
// 模拟网络:模拟发送一个 udp包
// 模拟网络:模拟发送一个 udp包
int udp_output(const char *buf, int len, ikcpcb *kcp, void *user)
{
union { int id; void *ptr; } parameter;
@ -26,18 +26,18 @@ int udp_output(const char *buf, int len, ikcpcb *kcp, void *user)
return 0;
}
// 测试用例
// 测试用例
void test(int mode)
{
// 创建模拟网络丢包率10%Rtt 60ms~125ms
// 创建模拟网络丢包率10%Rtt 60ms~125ms
vnet = new LatencySimulator(10, 60, 125);
// 创建两个端点的 kcp对象第一个参数 conv是会话编号同一个会话需要相同
// 最后一个是 user参数用来传递标识
// 创建两个端点的 kcp对象第一个参数 conv是会话编号同一个会话需要相同
// 最后一个是 user参数用来传递标识
ikcpcb *kcp1 = ikcp_create(0x11223344, (void*)0);
ikcpcb *kcp2 = ikcp_create(0x11223344, (void*)1);
// 设置kcp的下层输出这里为 udp_output模拟udp网络输出函数
// 设置kcp的下层输出这里为 udp_output模拟udp网络输出函数
kcp1->output = udp_output;
kcp2->output = udp_output;
@ -49,27 +49,27 @@ void test(int mode)
int count = 0;
int maxrtt = 0;
// 配置窗口大小平均延迟200ms每20ms发送一个包
// 而考虑到丢包重发设置最大收发窗口为128
// 配置窗口大小平均延迟200ms每20ms发送一个包
// 而考虑到丢包重发设置最大收发窗口为128
ikcp_wndsize(kcp1, 128, 128);
ikcp_wndsize(kcp2, 128, 128);
// 判断测试用例的模式
// 判断测试用例的模式
if (mode == 0) {
// 默认模式
// 默认模式
ikcp_nodelay(kcp1, 0, 10, 0, 0);
ikcp_nodelay(kcp2, 0, 10, 0, 0);
}
else if (mode == 1) {
// 普通模式,关闭流控等
// 普通模式,关闭流控等
ikcp_nodelay(kcp1, 0, 10, 0, 1);
ikcp_nodelay(kcp2, 0, 10, 0, 1);
} else {
// 启动快速模式
// 第二个参数 nodelay-启用以后若干常规加速将启动
// 第三个参数 interval为内部处理时钟默认设置为 10ms
// 第四个参数 resend为快速重传指标设置为2
// 第五个参数 为是否禁用常规流控,这里禁止
// 启动快速模式
// 第二个参数 nodelay-启用以后若干常规加速将启动
// 第三个参数 interval为内部处理时钟默认设置为 10ms
// 第四个参数 resend为快速重传指标设置为2
// 第五个参数 为是否禁用常规流控,这里禁止
ikcp_nodelay(kcp1, 1, 10, 2, 1);
ikcp_nodelay(kcp2, 1, 10, 2, 1);
kcp1->rx_minrto = 10;
@ -88,51 +88,51 @@ void test(int mode)
ikcp_update(kcp1, iclock());
ikcp_update(kcp2, iclock());
// 每隔 20mskcp1发送数据
// 每隔 20mskcp1发送数据
for (; current >= slap; slap += 20) {
((IUINT32*)buffer)[0] = index++;
((IUINT32*)buffer)[1] = current;
// 发送上层协议包
// 发送上层协议包
ikcp_send(kcp1, buffer, 8);
}
// 处理虚拟网络检测是否有udp包从p1->p2
// 处理虚拟网络检测是否有udp包从p1->p2
while (1) {
hr = vnet->recv(1, buffer, 2000);
if (hr < 0) break;
// 如果 p2收到udp则作为下层协议输入到kcp2
// 如果 p2收到udp则作为下层协议输入到kcp2
ikcp_input(kcp2, buffer, hr);
}
// 处理虚拟网络检测是否有udp包从p2->p1
// 处理虚拟网络检测是否有udp包从p2->p1
while (1) {
hr = vnet->recv(0, buffer, 2000);
if (hr < 0) break;
// 如果 p1收到udp则作为下层协议输入到kcp1
// 如果 p1收到udp则作为下层协议输入到kcp1
ikcp_input(kcp1, buffer, hr);
}
// kcp2接收到任何包都返回回去
// kcp2接收到任何包都返回回去
while (1) {
hr = ikcp_recv(kcp2, buffer, 10);
// 没有收到包就退出
// 没有收到包就退出
if (hr < 0) break;
// 如果收到包就回射
// 如果收到包就回射
ikcp_send(kcp2, buffer, hr);
}
// kcp1收到kcp2的回射数据
// kcp1收到kcp2的回射数据
while (1) {
hr = ikcp_recv(kcp1, buffer, 10);
// 没有收到包就退出
// 没有收到包就退出
if (hr < 0) break;
IUINT32 sn = *(IUINT32*)(buffer + 0);
IUINT32 ts = *(IUINT32*)(buffer + 4);
IUINT32 rtt = current - ts;
if (sn != next) {
// 如果收到的包不连续
// 如果收到的包不连续
printf("ERROR sn %d<->%d\n", (int)count, (int)next);
return;
}
@ -161,9 +161,9 @@ void test(int mode)
int main()
{
test(0); // 默认模式,类似 TCP正常模式无快速重传常规流控
test(1); // 普通模式,关闭流控等
test(2); // 快速模式,所有开关都打开,且关闭流控
test(0); // 默认模式,类似 TCP正常模式无快速重传常规流控
test(1); // 普通模式,关闭流控等
test(2); // 快速模式,所有开关都打开,且关闭流控
return 0;
}

22
test.h
View File

@ -83,7 +83,7 @@ static inline void isleep(unsigned long millisecond)
#include <list>
#include <vector>
// 带延迟的数据包
// 带延迟的数据包
class DelayPacket
{
public:
@ -113,7 +113,7 @@ protected:
IUINT32 _ts;
};
// 均匀分布的随机数
// 均匀分布的随机数
class Random
{
public:
@ -142,7 +142,7 @@ protected:
std::vector<int> seeds;
};
// 网络延迟模拟器
// 网络延迟模拟器
class LatencySimulator
{
public:
@ -151,20 +151,20 @@ public:
clear();
}
// lostrate: 往返一周丢包率的百分比,默认 10%
// rttminrtt最小值默认 60
// rttmaxrtt最大值默认 125
// lostrate: 往返一周丢包率的百分比,默认 10%
// rttminrtt最小值默认 60
// rttmaxrtt最大值默认 125
LatencySimulator(int lostrate = 10, int rttmin = 60, int rttmax = 125, int nmax = 1000):
r12(100), r21(100) {
current = iclock();
this->lostrate = lostrate / 2; // 上面数据是往返丢包率单程除以2
this->lostrate = lostrate / 2; // 上面数据是往返丢包率单程除以2
this->rttmin = rttmin / 2;
this->rttmax = rttmax / 2;
this->nmax = nmax;
tx1 = tx2 = 0;
}
// 清除数据
// 清除数据
void clear() {
DelayTunnel::iterator it;
for (it = p12.begin(); it != p12.end(); it++) {
@ -177,8 +177,8 @@ public:
p21.clear();
}
// 发送数据
// peer - 端点0/1从0发送从1接收从1发送从0接收
// 发送数据
// peer - 端点0/1从0发送从1接收从1发送从0接收
void send(int peer, const void *data, int size) {
if (peer == 0) {
tx1++;
@ -201,7 +201,7 @@ public:
}
}
// 接收数据
// 接收数据
int recv(int peer, void *data, int maxsize) {
DelayTunnel::iterator it;
if (peer == 0) {