Skip to content
/ m_net Public

cross platform network library with TLS extension, support LuaJIT's pull style API, using epoll/kqueue/wepoll underlying.

License

Notifications You must be signed in to change notification settings

lalawue/m_net

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MIT licensed [![Build Status][3]][4]

About

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.

Features

  • 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

Server

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

Client

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.

Lua/LuaJIT Wrapper

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.

DNS query

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 ...

OpenSSL support

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

Example

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/openssl@1.1/1.1.1k/ $ export DYLD_LIBRARY_PATH=/usr/local/Cellar/openssl@1.1/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.

LuaJIT TLS wrapper

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

Multi-process

please refers to exmaples/process/

Tests

only point to point testing, no unit test right now.

Core Test

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

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

Example

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.

Benchmark

Intel 12700F 64G, server and wrk in same PC.

C API

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 

CPP API

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 

LuaJIT

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 

Lua 5.4.4

$ 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 

Projects

  • 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

Thanks NTP source code from https://github.com/edma2/ntp, author: Eugene Ma (edma2)

About

cross platform network library with TLS extension, support LuaJIT's pull style API, using epoll/kqueue/wepoll underlying.

Topics

Resources

License

Stars

Watchers

Forks