-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
tcp_echo_server.c
143 lines (128 loc) · 3.58 KB
/
tcp_echo_server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* tcp echo server
*
* @build make examples
* @server bin/tcp_echo_server 1234
* @client bin/nc 127.0.0.1 1234
* nc 127.0.0.1 1234
* telnet 127.0.0.1 1234
*/
#include "hloop.h"
#include "hsocket.h"
#include "hssl.h"
/*
* @test ssl_server
* #define TEST_SSL 1
*
* @build ./configure --with-openssl && make clean && make
* @server bin/tcp_echo_server 1234
* @client bin/nc -s 127.0.0.1 1234
*
*/
#define TEST_SSL 0
#define TEST_READ_ONCE 0
#define TEST_READLINE 0
#define TEST_READSTRING 0
#define TEST_READBYTES 0
#define TEST_READ_STOP 0
#define TEST_UNPACK 0
#if TEST_UNPACK
static unpack_setting_t unpack_setting;
#endif
// hloop_create_tcp_server -> on_accept -> hio_read -> on_recv -> hio_write
static void on_close(hio_t* io) {
printf("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
}
static void on_recv(hio_t* io, void* buf, int readbytes) {
printf("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
char localaddrstr[SOCKADDR_STRLEN] = {0};
char peeraddrstr[SOCKADDR_STRLEN] = {0};
printf("[%s] <=> [%s]\n",
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
printf("< %.*s", readbytes, (char*)buf);
// echo
printf("> %.*s", readbytes, (char*)buf);
hio_write(io, buf, readbytes);
#if TEST_READ_STOP
hio_read_stop(io);
#elif TEST_READ_ONCE
hio_read_once(io);
#elif TEST_READLINE
hio_readline(io);
#elif TEST_READSTRING
hio_readstring(io);
#elif TEST_READBYTES
hio_readbytes(io, TEST_READBYTES);
#endif
}
static void on_accept(hio_t* io) {
printf("on_accept connfd=%d\n", hio_fd(io));
char localaddrstr[SOCKADDR_STRLEN] = {0};
char peeraddrstr[SOCKADDR_STRLEN] = {0};
printf("accept connfd=%d [%s] <= [%s]\n", hio_fd(io),
SOCKADDR_STR(hio_localaddr(io), localaddrstr),
SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
hio_setcb_close(io, on_close);
hio_setcb_read(io, on_recv);
#if TEST_UNPACK
hio_set_unpack(io, &unpack_setting);
#endif
#if TEST_READ_ONCE
hio_read_once(io);
#elif TEST_READLINE
hio_readline(io);
#elif TEST_READSTRING
hio_readstring(io);
#elif TEST_READBYTES
hio_readbytes(io, TEST_READBYTES);
#else
hio_read_start(io);
#endif
}
int main(int argc, char** argv) {
if (argc < 2) {
printf("Usage: %s port|path\n", argv[0]);
return -10;
}
const char* host = "0.0.0.0";
int port = atoi(argv[1]);
#if ENABLE_UDS
if (port == 0) {
host = argv[1];
port = -1;
}
#endif
#if TEST_UNPACK
memset(&unpack_setting, 0, sizeof(unpack_setting_t));
unpack_setting.package_max_length = DEFAULT_PACKAGE_MAX_LENGTH;
unpack_setting.mode = UNPACK_BY_DELIMITER;
unpack_setting.delimiter[0] = '\r';
unpack_setting.delimiter[1] = '\n';
unpack_setting.delimiter_bytes = 2;
#endif
hloop_t* loop = hloop_new(0);
#if TEST_SSL
hio_t* listenio = hloop_create_ssl_server(loop, host, port, on_accept);
#else
hio_t* listenio = hloop_create_tcp_server(loop, host, port, on_accept);
#endif
if (listenio == NULL) {
return -20;
}
#if TEST_SSL
hssl_ctx_opt_t ssl_param;
memset(&ssl_param, 0, sizeof(ssl_param));
ssl_param.crt_file = "cert/server.crt";
ssl_param.key_file = "cert/server.key";
ssl_param.endpoint = HSSL_SERVER;
if (hio_new_ssl_ctx(listenio, &ssl_param) != 0) {
fprintf(stderr, "hssl_ctx_new failed!\n");
return -30;
}
#endif
printf("listenfd=%d\n", hio_fd(listenio));
hloop_run(loop);
hloop_free(&loop);
return 0;
}