- About
- Features
- Server
- Client
- Lua/LuaJIT Wrapper
- DNS query
- OpenSSL support
- Multi-process
- Tests
- Example
- Benchmark
- Projects
- Thanks
m_net was a single file cross platform network library, provide a simple and efficient interface for covenient use.
Also support Lua/LuaJIT with pull style API interface.
Support Linux/MacOS/FreeBSD/Windows, using epoll/kqueue/wepoll underlying.
Please use gmake to build demo under FreeBSD.
- with TCP/UDP support
- nonblocking & event driven interface
- using epoll/kqueue/wepoll in Linux/MacOS/FreeBSD/Windows
- support Lua/LuaJIT with pull style API
- buildin timer event
- simple API in C++ wrapper
- support SSL/TLS with OpenSSL extension
- extension skeleton on top of bare socket TCP/UDP
- support multi-process
It's very convenience for use, an echo server example, with CPP wrapper:
// subclass Chann to handle event
class CntChann : public Chann {
public:
CntChann(Chann *c) : Chann(c) {}
// implement virtual defaultEventHandler
void defaultEventHandler(Chann *accept, chann_event_t event, int err) {
if (event == CHANN_EVENT_RECV) {
int ret = channRecv(m_buf, 256);
channSend(m_buf, ret);
} else if (event == CHANN_EVENT_DISCONNECT) {
delete this; // release chann
}
}
char m_buf[256];
};
int main(int argc, char *argv[]) {
if (argc < 2) {
cout << argv[0] << ": 'svr_ip:port'" << endl;
} else {
Chann echoSvr("tcp");
if ( echoSvr.channListen(argv[1]) ) {
cout << "svr start listen: " << argv[1] << endl;
echoSvr.setEventHandler([](Chann *self, Chann *accept, chann_event_t event, int err) {
if (event == CHANN_EVENT_ACCEPT) {
CntChann *cnt = new CntChann(accept);
char welcome[] = "Welcome to echoServ\n";
cnt->channSend((void*)welcome, sizeof(welcome));
delete accept;
}
});
ChannDispatcher::startEventLoop();
}
}
return 0;
}
the nested code need Closure support, with environment:
- Apple LLVM version 8.1.0 (clang-802.0.42)
- g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
with bare C:
static void
_on_cnt_event(chann_msg_t *msg) {
if (msg->event == CHANN_EVENT_RECV) {
char buf[256] = {0};
if (mnet_chann_recv(msg->n, buf, 256) > 0) {
printf("%s", buf);;
if ( fgets(buf, 256, stdin) ) {
mnet_chann_send(msg->n, buf, strlen(buf));
} else {
mnet_chann_close(msg->n);
}
}
} else if (msg->event == CHANN_EVENT_DISCONNECT) {
mnet_chann_close(msg->n);
}
}
int
main(int argc, char *argv[]) {
if (argc < 2) {
printf("%s 'cnt_ip:port'\n", argv[0]);
} else {
chann_addr_t addr;
if (mnet_parse_ipport(argv[1], &addr) > 0) {
mnet_init();
chann_t *cnt = mnet_chann_open(CHANN_TYPE_STREAM);
printf("cnt try connect %s:%d...\n", addr.ip, addr.port);
mnet_chann_connect(cnt, addr.ip, addr.port);
while (mnet_poll(1000000) > 0 {
chann_msg_t *msg = NULL;
while ((msg = mnet_result_next()) {
_on_cnt_event(msg);
}
}
mnet_fini();
}
}
return 0;
}
In the other hand, the C interface with more flexible options.
recommand using LuaRocks to build, then run examples/chann_web.lua
$ luarocks make
$ lua examples/chann_web.lua
open browser to visit 'http://127.0.0.1:8080' and get README.md
plain text, and you will get browser's request infomation in terminal side.
add DNS query interface with LuaJIT binding, in extension/mdns
dir, default query www.baidu.com
$ luajit examples/test_mdns.lua www.github.com www.sina.com
using LuaJIT 2.1.0-beta3
---
query www.baidu.com 14.215.177.39
query www.github.com 13.250.177.223
query www.sina.com 113.96.179.243
Or
you can get a bare C DNS query with:
$ export DYLD_LIBRARY_PATH=build
$ export LD_LIBRARY_PATH=build
$ ./build/ntp.out
try resolve 'cn.ntp.org.cn' ...
ntp: try connect to '114.118.7.161:123'
ntp: get response from ntp server:
RAW data below:
----------------
LI: 0
VN: 4
...
provide OpenSSL extension to wrap a SSL/TLS chann, two steps to create a TLS chann in C:
mnet_tls_config(SSL_CTX *ctx);
chann_t *n = mnet_chann_open(CHANN_TYPE_TLS);
// use chann to listen/accept/connect/recv/send TLS data like normal TCP STREAM
first build with openssl extension with command below, I install openssl with brew under MacOS.
(or you can luarocks install rockspecs/mnet-openssl-1.rockspec
under Linux)
$ export MNET_OPENSSL_DIR=/usr/local/Cellar/[email protected]/1.1.1k/
$ export DYLD_LIBRARY_PATH=/usr/local/Cellar/[email protected]/1.1.1k/lib/
$ make openssl
then run server
$ ./build/tls_svr
and client
$ ./build/tls_cnt
get testing code and readme under examples/openssl/ dir.
ffi-mnet under extension/luajit/
also support OpenSSL after you build libary support and export LD_LIBRARY_PATH
or export DYLD_LIBRARY_PATH
.
$ export LUA_PATH=./extension/luajit/?.lua
$ export LUA_CPATH=./build/?.so
$ luajit examples/openssl/tls_web_svr.lua
then you can visit https://127.0.0.1:8080
with browser, or
$ curl -k https://127.0.0.1:8080
hello, world !
Details in tls_web_cnt.lua or tls_web_svr.lua
please refers to exmaples/process/
only point to point testing, no unit test right now.
C/C++ core test in test dir.
- test_reconnect: test multi channs (default 256 with 'ulimits -n') in client connect/disconnect server 5 times
- test_rwdata: client send sequence data with each byte from 0 ~ 255, and wanted same data back, up to 1 GB
- test_timer: test client invoke with random seconds, send data to server, close when running duration over 10 seconds
OpenSSL test in test/openssl/ dir.
- tls_test_reconnect: test multi channs (default 256 with 'ulimits -n') in client connect/disconnect server 5 times
- tls_test_rwdata: client send sequence data with each byte from 0 ~ 255, and wanted same data back, up to 1 GB
take simple example above, or details in examples.
including UDP/TCP, C/C++, timer event examples, also prvode Lua/LuaJIT one as a tiny web server.
Intel 12700F 64G, server and wrk in same PC.
benchmark for examples/chann_web.c
$ make example_c
$ ./build/chann_web_c.out
$ wrk -t8 -c200 --latency http://127.0.0.1:8080
Running 10s test @ http://127.0.0.1:8080
8 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.52ms 716.89us 16.20ms 76.31%
Req/Sec 9.82k 0.98k 18.08k 80.35%
Latency Distribution
50% 2.48ms
75% 2.73ms
90% 3.27ms
99% 4.97ms
785546 requests in 10.10s, 7.85GB read
Socket errors: connect 0, read 1310, write 0, timeout 0
Requests/sec: 77772.27
Transfer/sec: 795.91MB
benchmark for examples/chann_web.cpp
$ make example_cpp
$ ./build/chann_web_cpp.out
$ wrk -t8 -c200 --latency http://127.0.0.1:8080
Running 10s test @ http://127.0.0.1:8080
8 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.52ms 721.19us 11.40ms 67.74%
Req/Sec 9.81k 1.82k 15.47k 65.30%
Latency Distribution
50% 2.57ms
75% 2.83ms
90% 3.47ms
99% 4.04ms
787535 requests in 10.10s, 7.88GB read
Socket errors: connect 0, read 1062, write 0, timeout 0
Requests/sec: 77967.80
Transfer/sec: 798.73MB
benchmark for luajit examples/chann_web.lua
, first create mnet.so
$ make lib
$ cp build/libmnet.* build/mnet.so
$ export LD_LIBRARY_PATH=$PWD/build
$ export DYLD_LIBRARY_PATH=$PWD/build
$ export LUA_CPATH=./build/?.so
$ export LUA_PATH=./extension/luajit/?.lua
$ luajit examples/chann_web.lua
$ wrk -t8 -c200 --latency http://127.0.0.1:8080
Running 10s test @ http://127.0.0.1:8080
8 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.16ms 495.30us 5.83ms 74.90%
Req/Sec 11.61k 1.47k 26.65k 87.30%
Latency Distribution
50% 2.22ms
75% 2.49ms
90% 2.67ms
99% 3.07ms
927741 requests in 10.10s, 8.76GB read
Socket errors: connect 0, read 103, write 0, timeout 0
Requests/sec: 91857.05
Transfer/sec: 0.87GB
$ luarock make
$ lua examples/chann_web.lua
$ wrk -t8 -c200 --latency http://127.0.0.1:8080
Running 10s test @ http://127.0.0.1:8080
8 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.51ms 800.51us 73.30ms 94.13%
Req/Sec 10.03k 0.92k 13.18k 63.24%
Latency Distribution
50% 2.51ms
75% 2.82ms
90% 2.90ms
99% 3.92ms
806331 requests in 10.10s, 8.06GB read
Socket errors: connect 0, read 88, write 0, timeout 0
Requests/sec: 79828.78
Transfer/sec: 816.96MB
- cincau: a fast, minimalist and high configurable framework for LuaJIT based on m_net or openresty (nginx)
- rpc_core: LuaJIT base network RPC framework for MacOS/Linux/FreeBSD/Windows.
Thanks NTP source code from https://github.com/edma2/ntp, author: Eugene Ma (edma2)