From 64807cecb0967fb17ce803b232313c8df17458ec Mon Sep 17 00:00:00 2001 From: whenif Date: Sun, 8 Jan 2017 17:16:06 +0800 Subject: [PATCH 1/4] Add files via upload --- lkcp.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++ testkcp.lua | 187 ++++++++++++++++++++++++++++++++++ 2 files changed, 469 insertions(+) create mode 100644 lkcp.c create mode 100644 testkcp.lua diff --git a/lkcp.c b/lkcp.c new file mode 100644 index 0000000..c167871 --- /dev/null +++ b/lkcp.c @@ -0,0 +1,282 @@ +/** + * + * Copyright (C) 2015 by David Lin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING IN + * THE SOFTWARE. + * + */ + +#include +#include +#include + +#include +#include + +#include "ikcp.h" + +#define RECV_BUFFER_LEN 4*1024*1024 + +#define check_kcp(L, idx)\ + *(ikcpcb**)luaL_checkudata(L, idx, "kcp_meta") + +#define check_buf(L, idx)\ + (char*)luaL_checkudata(L, idx, "recv_buffer") + +struct Callback { + uint64_t handle; + lua_State* L; +}; + +static int kcp_output_callback(const char *buf, int len, ikcpcb *kcp, void *arg) { + struct Callback* c = (struct Callback*)arg; + lua_State* L = c -> L; + uint64_t handle = c -> handle; + lua_pushstring(L, "kcp-cbs"); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushinteger(L, handle); + lua_rawget(L, -2); + lua_pushlstring(L, buf, len); + + int status = lua_pcall(L, 1, 0, 0); + if (status) { + lua_pop(L, 1); + } + lua_pop(L, 1); + return 0; +} + +static int kcp_gc(lua_State* L) { + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + return 0; + } + if (kcp->user != NULL) { + struct Callback* c = (struct Callback*)kcp -> user; + uint64_t handle = c -> handle; + lua_pushstring(L, "kcp-cbs"); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushinteger(L, handle); + lua_pushnil(L); + lua_rawset(L, -3); + lua_pop(L, 1); + free(c); + kcp->user = NULL; + } + ikcp_release(kcp); + kcp = NULL; + return 0; +} + +static int lkcp_create(lua_State* L){ + int32_t conv = luaL_checkinteger(L, 1); + uint64_t idx = luaL_checkinteger(L, 2); + lua_pushstring(L, "kcp-cbs"); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushinteger(L, idx); + lua_pushvalue(L, 3); + lua_rawset(L, -3); + lua_pop(L, 1); + + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); + lua_State* mL = lua_tothread(L, -1); + lua_pop(L, 1); + + struct Callback* c = malloc(sizeof(struct Callback)); + memset(c, 0, sizeof(struct Callback)); + c -> handle = idx; + c -> L = mL; + + ikcpcb* kcp = ikcp_create(conv, (void*)c); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: fail to create kcp"); + return 2; + } + + kcp->output = kcp_output_callback; + + *(ikcpcb**)lua_newuserdata(L, sizeof(void*)) = kcp; + luaL_getmetatable(L, "kcp_meta"); + lua_setmetatable(L, -2); + return 1; +} + +static int lkcp_recv(lua_State* L){ + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: kcp not args"); + return 2; + } + lua_getfield(L, LUA_REGISTRYINDEX, "kcp_lua_recv_buffer"); + char* buf = check_buf(L, -1); + lua_pop(L, 1); + + int32_t hr = ikcp_recv(kcp, buf, RECV_BUFFER_LEN); + if (hr <= 0) { + lua_pushinteger(L, hr); + return 1; + } + + lua_pushinteger(L, hr); + lua_pushlstring(L, (const char *)buf, hr); + + return 2; +} + +static int lkcp_send(lua_State* L){ + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: kcp not args"); + return 2; + } + size_t size; + const char *data = luaL_checklstring(L, 2, &size); + int32_t hr = ikcp_send(kcp, data, size); + + lua_pushinteger(L, hr); + return 1; +} + +static int lkcp_update(lua_State* L){ + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: kcp not args"); + return 2; + } + int32_t current = luaL_checkinteger(L, 2); + ikcp_update(kcp, current); + return 0; +} + +static int lkcp_check(lua_State* L){ + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: kcp not args"); + return 2; + } + int32_t current = luaL_checkinteger(L, 2); + int32_t hr = ikcp_check(kcp, current); + lua_pushinteger(L, hr); + return 1; +} + +static int lkcp_input(lua_State* L){ + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: kcp not args"); + return 2; + } + size_t size; + const char *data = luaL_checklstring(L, 2, &size); + int32_t hr = ikcp_input(kcp, data, size); + + lua_pushinteger(L, hr); + return 1; +} + +static int lkcp_flush(lua_State* L){ + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: kcp not args"); + return 2; + } + ikcp_flush(kcp); + return 0; +} + +static int lkcp_wndsize(lua_State* L){ + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: kcp not args"); + return 2; + } + int32_t sndwnd = luaL_checkinteger(L, 2); + int32_t rcvwnd = luaL_checkinteger(L, 3); + ikcp_wndsize(kcp, sndwnd, rcvwnd); + return 0; +} + +static int lkcp_nodelay(lua_State* L){ + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { + lua_pushnil(L); + lua_pushstring(L, "error: kcp not args"); + return 2; + } + int32_t nodelay = luaL_checkinteger(L, 2); + int32_t interval = luaL_checkinteger(L, 3); + int32_t resend = luaL_checkinteger(L, 4); + int32_t nc = luaL_checkinteger(L, 5); + int32_t hr = ikcp_nodelay(kcp, nodelay, interval, resend, nc); + lua_pushinteger(L, hr); + return 1; +} + + +static const struct luaL_Reg lkcp_methods [] = { + { "lkcp_recv" , lkcp_recv }, + { "lkcp_send" , lkcp_send }, + { "lkcp_update" , lkcp_update }, + { "lkcp_check" , lkcp_check }, + { "lkcp_input" , lkcp_input }, + { "lkcp_flush" , lkcp_flush }, + { "lkcp_wndsize" , lkcp_wndsize }, + { "lkcp_nodelay" , lkcp_nodelay }, + {NULL, NULL}, +}; + +static const struct luaL_Reg l_methods[] = { + { "lkcp_create" , lkcp_create }, + {NULL, NULL}, +}; + +int luaopen_lkcp(lua_State* L) { + luaL_checkversion(L); + lua_pushstring(L, "kcp-cbs"); + lua_newtable(L); + lua_rawset(L, LUA_REGISTRYINDEX); + luaL_newmetatable(L, "kcp_meta"); + + lua_newtable(L); + luaL_setfuncs(L, lkcp_methods, 0); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, kcp_gc); + lua_setfield(L, -2, "__gc"); + + luaL_newmetatable(L, "recv_buffer"); + + char* global_recv_buffer = lua_newuserdata(L, sizeof(char)*RECV_BUFFER_LEN); + memset(global_recv_buffer, 0, sizeof(char)*RECV_BUFFER_LEN); + luaL_getmetatable(L, "recv_buffer"); + lua_setmetatable(L, -2); + lua_setfield(L, LUA_REGISTRYINDEX, "kcp_lua_recv_buffer"); + + luaL_newlib(L, l_methods); + + return 1; +} + diff --git a/testkcp.lua b/testkcp.lua new file mode 100644 index 0000000..44cb460 --- /dev/null +++ b/testkcp.lua @@ -0,0 +1,187 @@ + +package.cpath=package.cpath..";./lualib/?.so" +package.path=package.path..";./src/?.lua" + + +local LatencySM = require "latencysm" +local LKcp = require "lkcp" +local LUtil = require "lutil" + +--创建模拟网络:丢包率10%,RTT 60-125ms +local lsm = LatencySM.LatencySM.new(10, 60, 125) + + +local function getms() + return math.floor(LUtil.gettimeofday()) +end + +local function udp_output(buf, info) + print(info.id, info.a, info.b, info.c) + if info.b then + info.c(info.a) + end + lsm:send(info.id, buf) +end + +local function test(mode) + --此处info用于output接口回调数据 + local session = 0x11223344 + local info = { + id = 0, + a = 'aaa', + b = false, + } + local kcp1 = LKcp.lkcp_create(session, 1, function (buf) + udp_output(buf, info) + end) + local info2 = { + id = 1, + a = 'aaaaaaaaaaaaa', + b = true, + c = function (a) + print 'hahahah!!!' + end, + } + local kcp2 = LKcp.lkcp_create(session, 2, function (buf) + udp_output(buf, info2) + end) + + local current = getms() + local slap = current + 20 + local index = 0 + local inext = 0 + local sumrtt = 0 + + local count = 0 + local maxrtt = 0 + + --配置窗口大小:平均延迟200ms,每20ms发送一个包, + --而考虑到丢包重发,设置最大收发窗口为128 + kcp1:lkcp_wndsize(128, 128) + kcp2:lkcp_wndsize(128, 128) + + --判断测试用例的模式 + if mode == 0 then + --默认模式 + kcp1:lkcp_nodelay(0, 10, 0, 0) + kcp2:lkcp_nodelay(0, 10, 0, 0) + elseif mode == 1 then + --普通模式,关闭流控等 + kcp1:lkcp_nodelay(0, 10, 0, 1) + kcp2:lkcp_nodelay(0, 10, 0, 1) + else + --启动快速模式 + --第二个参数 nodelay-启用以后若干常规加速将启动 + --第三个参数 interval为内部处理时钟,默认设置为 10ms + --第四个参数 resend为快速重传指标,设置为2 + --第五个参数 为是否禁用常规流控,这里禁止 + kcp1:lkcp_nodelay(1, 10, 2, 1) + kcp2:lkcp_nodelay(1, 10, 2, 1) + end + + local buffer = "" + local hrlen = 0 + local hr = "" + local ts1 = getms() + + while 1 do + current = getms() + + local nextt1 = kcp1:lkcp_check(current) + local nextt2 = kcp2:lkcp_check(current) + local nextt = math.min(nextt1, nextt2) + local diff = nextt - current + if diff > 0 then + LUtil.isleep(diff) + current = getms() + end + + kcp1:lkcp_update(current) + kcp2:lkcp_update(current) + + --每隔 20ms,kcp1发送数据 + while current >= slap do + local s1 = LUtil.uint322netbytes(index) + local s2 = LUtil.uint322netbytes(current) + kcp1:lkcp_send(s1..s2) + --kcp1:lkcp_flush() + slap = slap + 20 + index = index + 1 + end + --处理虚拟网络:检测是否有udp包从p1->p2 + while 1 do + hrlen, hr = lsm:recv(1) + if hrlen < 0 then + break + end + --如果 p2收到udp,则作为下层协议输入到kcp2 + kcp2:lkcp_input(hr) + end + + --处理虚拟网络:检测是否有udp包从p2->p1 + while 1 do + hrlen, hr = lsm:recv(0) + if hrlen < 0 then + break + end + --如果 p1收到udp,则作为下层协议输入到kcp1 + kcp1:lkcp_input(hr) + end + + --kcp2接收到任何包都返回回去 + while 1 do + hrlen, hr = kcp2:lkcp_recv() + if hrlen <= 0 then + break + end + kcp2:lkcp_send(hr) + --kcp2:lkcp_flush() + end + + --kcp1收到kcp2的回射数据 + while 1 do + hrlen, hr = kcp1:lkcp_recv() + --没有收到包就退出 + if hrlen <= 0 then + break + end + + local hr1 = string.sub(hr, 1, 4) + local hr2 = string.sub(hr, 5, 8) + local sn = LUtil.netbytes2uint32(hr1) + local ts = LUtil.netbytes2uint32(hr2) + local rtt = current - ts + + if sn ~= inext then + --如果收到的包不连续 + print(string.format("ERROR sn %d<->%d\n", count, inext)) + return + end + + inext = inext + 1 + sumrtt = sumrtt + rtt + count = count + 1 + if rtt > maxrtt then + maxrtt = rtt + end + + print(string.format("[RECV] mode=%d sn=%d rtt=%d\n", mode, sn, rtt)) + end + if inext > 10 then + break + end + end + + ts1 = getms() - ts1 + names = {"default", "normal", "fast"} + print(string.format("%s mode result (%dms):", names[mode+1], ts1)) + print(string.format("avgrtt=%d maxrtt=%d", math.floor(sumrtt/count), maxrtt)) + print("press enter to next ...") + io.read() +end + +--测试 +test(0) --默认模式,类似 TCP:正常模式,无快速重传,常规流控 +test(1) --普通模式,关闭流控等 +test(2) --快速模式,所有开关都打开,且关闭流控 + From 7bfc6c8c14553014e69902b973909a32ef062f25 Mon Sep 17 00:00:00 2001 From: whenif Date: Sun, 8 Jan 2017 17:17:20 +0800 Subject: [PATCH 2/4] Add files via upload --- src/lkcp.c | 45 +++++++++++++----- src/testkcp.lua | 119 ++++++++++++++++++++++++------------------------ 2 files changed, 93 insertions(+), 71 deletions(-) diff --git a/src/lkcp.c b/src/lkcp.c index 844f5de..c167871 100644 --- a/src/lkcp.c +++ b/src/lkcp.c @@ -48,23 +48,34 @@ static int kcp_output_callback(const char *buf, int len, ikcpcb *kcp, void *arg) struct Callback* c = (struct Callback*)arg; lua_State* L = c -> L; uint64_t handle = c -> handle; - - lua_rawgeti(L, LUA_REGISTRYINDEX, handle); + lua_pushstring(L, "kcp-cbs"); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushinteger(L, handle); + lua_rawget(L, -2); lua_pushlstring(L, buf, len); - lua_call(L, 1, 0); + int status = lua_pcall(L, 1, 0, 0); + if (status) { + lua_pop(L, 1); + } + lua_pop(L, 1); return 0; } static int kcp_gc(lua_State* L) { - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { + ikcpcb* kcp = check_kcp(L, 1); + if (kcp == NULL) { return 0; - } + } if (kcp->user != NULL) { struct Callback* c = (struct Callback*)kcp -> user; uint64_t handle = c -> handle; - luaL_unref(L, LUA_REGISTRYINDEX, handle); + lua_pushstring(L, "kcp-cbs"); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushinteger(L, handle); + lua_pushnil(L); + lua_rawset(L, -3); + lua_pop(L, 1); free(c); kcp->user = NULL; } @@ -74,13 +85,23 @@ static int kcp_gc(lua_State* L) { } static int lkcp_create(lua_State* L){ - uint64_t handle = luaL_ref(L, LUA_REGISTRYINDEX); int32_t conv = luaL_checkinteger(L, 1); + uint64_t idx = luaL_checkinteger(L, 2); + lua_pushstring(L, "kcp-cbs"); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushinteger(L, idx); + lua_pushvalue(L, 3); + lua_rawset(L, -3); + lua_pop(L, 1); + + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); + lua_State* mL = lua_tothread(L, -1); + lua_pop(L, 1); struct Callback* c = malloc(sizeof(struct Callback)); memset(c, 0, sizeof(struct Callback)); - c -> handle = handle; - c -> L = L; + c -> handle = idx; + c -> L = mL; ikcpcb* kcp = ikcp_create(conv, (void*)c); if (kcp == NULL) { @@ -235,7 +256,9 @@ static const struct luaL_Reg l_methods[] = { int luaopen_lkcp(lua_State* L) { luaL_checkversion(L); - + lua_pushstring(L, "kcp-cbs"); + lua_newtable(L); + lua_rawset(L, LUA_REGISTRYINDEX); luaL_newmetatable(L, "kcp_meta"); lua_newtable(L); diff --git a/src/testkcp.lua b/src/testkcp.lua index f1b3e56..44cb460 100644 --- a/src/testkcp.lua +++ b/src/testkcp.lua @@ -31,7 +31,7 @@ local function test(mode) a = 'aaa', b = false, } - local kcp1 = LKcp.lkcp_create(session, function (buf) + local kcp1 = LKcp.lkcp_create(session, 1, function (buf) udp_output(buf, info) end) local info2 = { @@ -42,7 +42,7 @@ local function test(mode) print 'hahahah!!!' end, } - local kcp2 = LKcp.lkcp_create(session, function (buf) + local kcp2 = LKcp.lkcp_create(session, 2, function (buf) udp_output(buf, info2) end) @@ -108,69 +108,68 @@ local function test(mode) slap = slap + 20 index = index + 1 end - - --处理虚拟网络:检测是否有udp包从p1->p2 - while 1 do - hrlen, hr = lsm:recv(1) - if hrlen < 0 then - break - end - --如果 p2收到udp,则作为下层协议输入到kcp2 - kcp2:lkcp_input(hr) - end - - --处理虚拟网络:检测是否有udp包从p2->p1 - while 1 do - hrlen, hr = lsm:recv(0) - if hrlen < 0 then - break - end - --如果 p1收到udp,则作为下层协议输入到kcp1 - kcp1:lkcp_input(hr) - end - - --kcp2接收到任何包都返回回去 - while 1 do - hrlen, hr = kcp2:lkcp_recv() - if hrlen <= 0 then - break + --处理虚拟网络:检测是否有udp包从p1->p2 + while 1 do + hrlen, hr = lsm:recv(1) + if hrlen < 0 then + break + end + --如果 p2收到udp,则作为下层协议输入到kcp2 + kcp2:lkcp_input(hr) + end + + --处理虚拟网络:检测是否有udp包从p2->p1 + while 1 do + hrlen, hr = lsm:recv(0) + if hrlen < 0 then + break + end + --如果 p1收到udp,则作为下层协议输入到kcp1 + kcp1:lkcp_input(hr) end - kcp2:lkcp_send(hr) - --kcp2:lkcp_flush() - end - --kcp1收到kcp2的回射数据 - while 1 do - hrlen, hr = kcp1:lkcp_recv() - --没有收到包就退出 - if hrlen <= 0 then - break + --kcp2接收到任何包都返回回去 + while 1 do + hrlen, hr = kcp2:lkcp_recv() + if hrlen <= 0 then + break + end + kcp2:lkcp_send(hr) + --kcp2:lkcp_flush() end - local hr1 = string.sub(hr, 1, 4) - local hr2 = string.sub(hr, 5, 8) - local sn = LUtil.netbytes2uint32(hr1) - local ts = LUtil.netbytes2uint32(hr2) - local rtt = current - ts + --kcp1收到kcp2的回射数据 + while 1 do + hrlen, hr = kcp1:lkcp_recv() + --没有收到包就退出 + if hrlen <= 0 then + break + end + + local hr1 = string.sub(hr, 1, 4) + local hr2 = string.sub(hr, 5, 8) + local sn = LUtil.netbytes2uint32(hr1) + local ts = LUtil.netbytes2uint32(hr2) + local rtt = current - ts - if sn ~= inext then - --如果收到的包不连续 - print(string.format("ERROR sn %d<->%d\n", count, inext)) - return - end - - inext = inext + 1 - sumrtt = sumrtt + rtt - count = count + 1 - if rtt > maxrtt then - maxrtt = rtt - end - - print(string.format("[RECV] mode=%d sn=%d rtt=%d\n", mode, sn, rtt)) - end - if inext > 10 then - break - end + if sn ~= inext then + --如果收到的包不连续 + print(string.format("ERROR sn %d<->%d\n", count, inext)) + return + end + + inext = inext + 1 + sumrtt = sumrtt + rtt + count = count + 1 + if rtt > maxrtt then + maxrtt = rtt + end + + print(string.format("[RECV] mode=%d sn=%d rtt=%d\n", mode, sn, rtt)) + end + if inext > 10 then + break + end end ts1 = getms() - ts1 From 8c6bc58b165444c012c687b491193dd2b4a09919 Mon Sep 17 00:00:00 2001 From: whenif Date: Sun, 8 Jan 2017 17:20:09 +0800 Subject: [PATCH 3/4] Delete testkcp.lua --- testkcp.lua | 187 ---------------------------------------------------- 1 file changed, 187 deletions(-) delete mode 100644 testkcp.lua diff --git a/testkcp.lua b/testkcp.lua deleted file mode 100644 index 44cb460..0000000 --- a/testkcp.lua +++ /dev/null @@ -1,187 +0,0 @@ - -package.cpath=package.cpath..";./lualib/?.so" -package.path=package.path..";./src/?.lua" - - -local LatencySM = require "latencysm" -local LKcp = require "lkcp" -local LUtil = require "lutil" - ---创建模拟网络:丢包率10%,RTT 60-125ms -local lsm = LatencySM.LatencySM.new(10, 60, 125) - - -local function getms() - return math.floor(LUtil.gettimeofday()) -end - -local function udp_output(buf, info) - print(info.id, info.a, info.b, info.c) - if info.b then - info.c(info.a) - end - lsm:send(info.id, buf) -end - -local function test(mode) - --此处info用于output接口回调数据 - local session = 0x11223344 - local info = { - id = 0, - a = 'aaa', - b = false, - } - local kcp1 = LKcp.lkcp_create(session, 1, function (buf) - udp_output(buf, info) - end) - local info2 = { - id = 1, - a = 'aaaaaaaaaaaaa', - b = true, - c = function (a) - print 'hahahah!!!' - end, - } - local kcp2 = LKcp.lkcp_create(session, 2, function (buf) - udp_output(buf, info2) - end) - - local current = getms() - local slap = current + 20 - local index = 0 - local inext = 0 - local sumrtt = 0 - - local count = 0 - local maxrtt = 0 - - --配置窗口大小:平均延迟200ms,每20ms发送一个包, - --而考虑到丢包重发,设置最大收发窗口为128 - kcp1:lkcp_wndsize(128, 128) - kcp2:lkcp_wndsize(128, 128) - - --判断测试用例的模式 - if mode == 0 then - --默认模式 - kcp1:lkcp_nodelay(0, 10, 0, 0) - kcp2:lkcp_nodelay(0, 10, 0, 0) - elseif mode == 1 then - --普通模式,关闭流控等 - kcp1:lkcp_nodelay(0, 10, 0, 1) - kcp2:lkcp_nodelay(0, 10, 0, 1) - else - --启动快速模式 - --第二个参数 nodelay-启用以后若干常规加速将启动 - --第三个参数 interval为内部处理时钟,默认设置为 10ms - --第四个参数 resend为快速重传指标,设置为2 - --第五个参数 为是否禁用常规流控,这里禁止 - kcp1:lkcp_nodelay(1, 10, 2, 1) - kcp2:lkcp_nodelay(1, 10, 2, 1) - end - - local buffer = "" - local hrlen = 0 - local hr = "" - local ts1 = getms() - - while 1 do - current = getms() - - local nextt1 = kcp1:lkcp_check(current) - local nextt2 = kcp2:lkcp_check(current) - local nextt = math.min(nextt1, nextt2) - local diff = nextt - current - if diff > 0 then - LUtil.isleep(diff) - current = getms() - end - - kcp1:lkcp_update(current) - kcp2:lkcp_update(current) - - --每隔 20ms,kcp1发送数据 - while current >= slap do - local s1 = LUtil.uint322netbytes(index) - local s2 = LUtil.uint322netbytes(current) - kcp1:lkcp_send(s1..s2) - --kcp1:lkcp_flush() - slap = slap + 20 - index = index + 1 - end - --处理虚拟网络:检测是否有udp包从p1->p2 - while 1 do - hrlen, hr = lsm:recv(1) - if hrlen < 0 then - break - end - --如果 p2收到udp,则作为下层协议输入到kcp2 - kcp2:lkcp_input(hr) - end - - --处理虚拟网络:检测是否有udp包从p2->p1 - while 1 do - hrlen, hr = lsm:recv(0) - if hrlen < 0 then - break - end - --如果 p1收到udp,则作为下层协议输入到kcp1 - kcp1:lkcp_input(hr) - end - - --kcp2接收到任何包都返回回去 - while 1 do - hrlen, hr = kcp2:lkcp_recv() - if hrlen <= 0 then - break - end - kcp2:lkcp_send(hr) - --kcp2:lkcp_flush() - end - - --kcp1收到kcp2的回射数据 - while 1 do - hrlen, hr = kcp1:lkcp_recv() - --没有收到包就退出 - if hrlen <= 0 then - break - end - - local hr1 = string.sub(hr, 1, 4) - local hr2 = string.sub(hr, 5, 8) - local sn = LUtil.netbytes2uint32(hr1) - local ts = LUtil.netbytes2uint32(hr2) - local rtt = current - ts - - if sn ~= inext then - --如果收到的包不连续 - print(string.format("ERROR sn %d<->%d\n", count, inext)) - return - end - - inext = inext + 1 - sumrtt = sumrtt + rtt - count = count + 1 - if rtt > maxrtt then - maxrtt = rtt - end - - print(string.format("[RECV] mode=%d sn=%d rtt=%d\n", mode, sn, rtt)) - end - if inext > 10 then - break - end - end - - ts1 = getms() - ts1 - names = {"default", "normal", "fast"} - print(string.format("%s mode result (%dms):", names[mode+1], ts1)) - print(string.format("avgrtt=%d maxrtt=%d", math.floor(sumrtt/count), maxrtt)) - print("press enter to next ...") - io.read() -end - ---测试 -test(0) --默认模式,类似 TCP:正常模式,无快速重传,常规流控 -test(1) --普通模式,关闭流控等 -test(2) --快速模式,所有开关都打开,且关闭流控 - From 0e1b221c2389f78e0542138d89fe433ff307662f Mon Sep 17 00:00:00 2001 From: whenif Date: Sun, 8 Jan 2017 17:20:57 +0800 Subject: [PATCH 4/4] Delete lkcp.c --- lkcp.c | 282 --------------------------------------------------------- 1 file changed, 282 deletions(-) delete mode 100644 lkcp.c diff --git a/lkcp.c b/lkcp.c deleted file mode 100644 index c167871..0000000 --- a/lkcp.c +++ /dev/null @@ -1,282 +0,0 @@ -/** - * - * Copyright (C) 2015 by David Lin - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING IN - * THE SOFTWARE. - * - */ - -#include -#include -#include - -#include -#include - -#include "ikcp.h" - -#define RECV_BUFFER_LEN 4*1024*1024 - -#define check_kcp(L, idx)\ - *(ikcpcb**)luaL_checkudata(L, idx, "kcp_meta") - -#define check_buf(L, idx)\ - (char*)luaL_checkudata(L, idx, "recv_buffer") - -struct Callback { - uint64_t handle; - lua_State* L; -}; - -static int kcp_output_callback(const char *buf, int len, ikcpcb *kcp, void *arg) { - struct Callback* c = (struct Callback*)arg; - lua_State* L = c -> L; - uint64_t handle = c -> handle; - lua_pushstring(L, "kcp-cbs"); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_pushinteger(L, handle); - lua_rawget(L, -2); - lua_pushlstring(L, buf, len); - - int status = lua_pcall(L, 1, 0, 0); - if (status) { - lua_pop(L, 1); - } - lua_pop(L, 1); - return 0; -} - -static int kcp_gc(lua_State* L) { - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - return 0; - } - if (kcp->user != NULL) { - struct Callback* c = (struct Callback*)kcp -> user; - uint64_t handle = c -> handle; - lua_pushstring(L, "kcp-cbs"); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_pushinteger(L, handle); - lua_pushnil(L); - lua_rawset(L, -3); - lua_pop(L, 1); - free(c); - kcp->user = NULL; - } - ikcp_release(kcp); - kcp = NULL; - return 0; -} - -static int lkcp_create(lua_State* L){ - int32_t conv = luaL_checkinteger(L, 1); - uint64_t idx = luaL_checkinteger(L, 2); - lua_pushstring(L, "kcp-cbs"); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_pushinteger(L, idx); - lua_pushvalue(L, 3); - lua_rawset(L, -3); - lua_pop(L, 1); - - lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); - lua_State* mL = lua_tothread(L, -1); - lua_pop(L, 1); - - struct Callback* c = malloc(sizeof(struct Callback)); - memset(c, 0, sizeof(struct Callback)); - c -> handle = idx; - c -> L = mL; - - ikcpcb* kcp = ikcp_create(conv, (void*)c); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: fail to create kcp"); - return 2; - } - - kcp->output = kcp_output_callback; - - *(ikcpcb**)lua_newuserdata(L, sizeof(void*)) = kcp; - luaL_getmetatable(L, "kcp_meta"); - lua_setmetatable(L, -2); - return 1; -} - -static int lkcp_recv(lua_State* L){ - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: kcp not args"); - return 2; - } - lua_getfield(L, LUA_REGISTRYINDEX, "kcp_lua_recv_buffer"); - char* buf = check_buf(L, -1); - lua_pop(L, 1); - - int32_t hr = ikcp_recv(kcp, buf, RECV_BUFFER_LEN); - if (hr <= 0) { - lua_pushinteger(L, hr); - return 1; - } - - lua_pushinteger(L, hr); - lua_pushlstring(L, (const char *)buf, hr); - - return 2; -} - -static int lkcp_send(lua_State* L){ - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: kcp not args"); - return 2; - } - size_t size; - const char *data = luaL_checklstring(L, 2, &size); - int32_t hr = ikcp_send(kcp, data, size); - - lua_pushinteger(L, hr); - return 1; -} - -static int lkcp_update(lua_State* L){ - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: kcp not args"); - return 2; - } - int32_t current = luaL_checkinteger(L, 2); - ikcp_update(kcp, current); - return 0; -} - -static int lkcp_check(lua_State* L){ - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: kcp not args"); - return 2; - } - int32_t current = luaL_checkinteger(L, 2); - int32_t hr = ikcp_check(kcp, current); - lua_pushinteger(L, hr); - return 1; -} - -static int lkcp_input(lua_State* L){ - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: kcp not args"); - return 2; - } - size_t size; - const char *data = luaL_checklstring(L, 2, &size); - int32_t hr = ikcp_input(kcp, data, size); - - lua_pushinteger(L, hr); - return 1; -} - -static int lkcp_flush(lua_State* L){ - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: kcp not args"); - return 2; - } - ikcp_flush(kcp); - return 0; -} - -static int lkcp_wndsize(lua_State* L){ - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: kcp not args"); - return 2; - } - int32_t sndwnd = luaL_checkinteger(L, 2); - int32_t rcvwnd = luaL_checkinteger(L, 3); - ikcp_wndsize(kcp, sndwnd, rcvwnd); - return 0; -} - -static int lkcp_nodelay(lua_State* L){ - ikcpcb* kcp = check_kcp(L, 1); - if (kcp == NULL) { - lua_pushnil(L); - lua_pushstring(L, "error: kcp not args"); - return 2; - } - int32_t nodelay = luaL_checkinteger(L, 2); - int32_t interval = luaL_checkinteger(L, 3); - int32_t resend = luaL_checkinteger(L, 4); - int32_t nc = luaL_checkinteger(L, 5); - int32_t hr = ikcp_nodelay(kcp, nodelay, interval, resend, nc); - lua_pushinteger(L, hr); - return 1; -} - - -static const struct luaL_Reg lkcp_methods [] = { - { "lkcp_recv" , lkcp_recv }, - { "lkcp_send" , lkcp_send }, - { "lkcp_update" , lkcp_update }, - { "lkcp_check" , lkcp_check }, - { "lkcp_input" , lkcp_input }, - { "lkcp_flush" , lkcp_flush }, - { "lkcp_wndsize" , lkcp_wndsize }, - { "lkcp_nodelay" , lkcp_nodelay }, - {NULL, NULL}, -}; - -static const struct luaL_Reg l_methods[] = { - { "lkcp_create" , lkcp_create }, - {NULL, NULL}, -}; - -int luaopen_lkcp(lua_State* L) { - luaL_checkversion(L); - lua_pushstring(L, "kcp-cbs"); - lua_newtable(L); - lua_rawset(L, LUA_REGISTRYINDEX); - luaL_newmetatable(L, "kcp_meta"); - - lua_newtable(L); - luaL_setfuncs(L, lkcp_methods, 0); - lua_setfield(L, -2, "__index"); - lua_pushcfunction(L, kcp_gc); - lua_setfield(L, -2, "__gc"); - - luaL_newmetatable(L, "recv_buffer"); - - char* global_recv_buffer = lua_newuserdata(L, sizeof(char)*RECV_BUFFER_LEN); - memset(global_recv_buffer, 0, sizeof(char)*RECV_BUFFER_LEN); - luaL_getmetatable(L, "recv_buffer"); - lua_setmetatable(L, -2); - lua_setfield(L, LUA_REGISTRYINDEX, "kcp_lua_recv_buffer"); - - luaL_newlib(L, l_methods); - - return 1; -} -