Skip to content

Commit afbee3e

Browse files
author
yuliang
committed
add example for kcp echo server
1 parent dbc0f0e commit afbee3e

File tree

2 files changed

+134
-1
lines changed

2 files changed

+134
-1
lines changed

examples/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ if(WITH_KCP)
7878
add_executable(kcptun_server ${KCPTUN_SMUX_FILES} ${KCPTUN_SERVER_FILES})
7979
target_link_libraries(kcptun_server ${HV_LIBRARIES})
8080

81-
list(APPEND EXAMPLES kcptun_client kcptun_server)
81+
add_executable(kcp_echo_server kcp_echo_server.c)
82+
target_link_libraries(kcp_echo_server ${HV_LIBRARIES})
83+
84+
add_executable(kcp_echo_client kcp_echo_server.c)
85+
target_link_libraries(kcp_echo_client ${HV_LIBRARIES})
86+
87+
list(APPEND EXAMPLES kcptun_client kcptun_server kcp_echo_server kcp_echo_client)
8288
endif()
8389

8490
if(WITH_EVPP)

examples/kcp_echo_server.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* kcp echo server
3+
*
4+
* @build mkdir build && cmake -B build -S . -DWITH_KCP=ON && cmake --build build --clean-first
5+
* @server bin/kcp_echo_server
6+
* @client bin/kcp_echo_client
7+
* @brief kcp echo server/client combining with hsignal, htimer, supported for auto-reconnect
8+
*
9+
*/
10+
#include <stdio.h>
11+
#include <stdint.h>
12+
#include <libgen.h>
13+
#include <signal.h>
14+
#include "hloop.h"
15+
#include "hsocket.h"
16+
17+
#define FLAG_KCP_EXIT (1 << 0)
18+
static uint32_t flags;
19+
static char *host = "127.0.0.1";
20+
static int port = 8888;
21+
static kcp_setting_t kcp_setting;
22+
static htimer_t *timer = NULL;
23+
24+
static hio_t *socket_open(hloop_t *loop);
25+
static void on_connect(hio_t *io);
26+
static void on_read(hio_t *io, void *buf, int readbytes);
27+
static void on_close(hio_t *io);
28+
29+
static hio_t *socket_open(hloop_t *loop)
30+
{
31+
intptr_t role = (intptr_t)hloop_userdata(loop);
32+
hio_t *io = (role == HIO_SERVER_SIDE ? hloop_create_udp_server : hloop_create_udp_client)(loop, host, port);
33+
hio_set_kcp(io, &kcp_setting);
34+
hio_setcb_read(io, on_read);
35+
hio_setcb_connect(io, on_connect);
36+
hio_setcb_close(io, on_close);
37+
38+
hio_read(io);
39+
if (role == HIO_CLIENT_SIDE)
40+
{
41+
hio_set_read_timeout(io, 2000);
42+
hio_connect(io);
43+
}
44+
45+
if (timer) hevent_set_userdata((hevent_t*)timer, io);
46+
return io;
47+
}
48+
49+
static void on_connect(hio_t *io)
50+
{
51+
if (hio_is_connected(io)) hio_read(io);
52+
char peeraddrstr[SOCKADDR_STRLEN] = {0};
53+
printf("connect with %s\n", SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
54+
}
55+
56+
static void on_read(hio_t *io, void *buf, int readbytes)
57+
{
58+
char localaddrstr[SOCKADDR_STRLEN] = {0};
59+
char peeraddrstr[SOCKADDR_STRLEN] = {0};
60+
intptr_t role = (intptr_t)hloop_userdata(hevent_loop(io));
61+
62+
if (readbytes <= 0) {printf("errno on recv!\n"); return;}
63+
printf("[%s] recv %d bytes from %s to %s--> buf: %.*s\n",
64+
role == HIO_SERVER_SIDE ? "server" : "client",
65+
readbytes,
66+
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr),
67+
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
68+
readbytes,
69+
(char*)buf);
70+
if (role == HIO_SERVER_SIDE) hio_write(io, buf, readbytes);
71+
}
72+
73+
static void on_close(hio_t *io)
74+
{
75+
char peeraddrstr[SOCKADDR_STRLEN] = {0};
76+
printf("disconnect from %s\n", SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
77+
if (!(flags & FLAG_KCP_EXIT))
78+
{
79+
intptr_t role = (intptr_t)hloop_userdata(hevent_loop(io));
80+
if (role == HIO_SERVER_SIDE) return;
81+
hloop_t *loop = hevent_loop(io);
82+
socket_open(loop);
83+
}
84+
}
85+
86+
static void signal_callback(hsignal_t* sig)
87+
{
88+
flags |= FLAG_KCP_EXIT;
89+
hloop_t *loop = hevent_loop(sig);
90+
uint64_t signo = hevent_id(sig);
91+
hloop_stop(loop);
92+
printf("signo %ld arrived, exiting event loop at %p\n", signo, loop);
93+
}
94+
95+
static void timer_callback(htimer_t* timer)
96+
{
97+
hio_t *io = (hio_t*)hevent_userdata(timer);
98+
intptr_t role = (intptr_t)hloop_userdata(hevent_loop(io));
99+
if (hio_is_connected(io) && role == HIO_CLIENT_SIDE) hio_write(io, "hello world", 1500);
100+
}
101+
102+
int main(int argc, char *argv[])
103+
{
104+
int role = HIO_SERVER_SIDE;
105+
if (strstr(basename(argv[0]), "server")) role = HIO_SERVER_SIDE;
106+
if (strstr(basename(argv[0]), "client")) role = HIO_CLIENT_SIDE;
107+
108+
if (argc > 1) role = atoi(argv[1]);
109+
if (argc > 2) host = argv[2];
110+
if (argc > 3) port = atoi(argv[3]);
111+
hloop_t *loop = hloop_new(0);
112+
hloop_set_userdata(loop, (void*)(intptr_t)role);
113+
timer = htimer_add(loop, timer_callback, 1000, INFINITE);
114+
kcp_setting_init_with_fast_mode(&kcp_setting);
115+
// more kcp settings like conv...
116+
kcp_setting.rcv_bufsize = (3 * 1024);
117+
118+
socket_open(loop);
119+
120+
hsignal_add(loop, signal_callback, SIGINT);
121+
hsignal_add(loop, signal_callback, SIGTERM);
122+
hsignal_add(loop, signal_callback, SIGQUIT);
123+
124+
hloop_run(loop);
125+
hloop_free(&loop);
126+
return 0;
127+
}

0 commit comments

Comments
 (0)