To write a echo server in C.
const int TOKEN_LISTENER = 1;
const int TOKEN_STREAM = 2;
struct cio_listener *listener = cio_listener_bind("tcp://127.0.0.1:6000");
struct cio *ctx = cio_new();
cio_register(ctx, cio_listener_getfd(listener), TOKEN_LISTENER, CIOF_READABLE, listener);
for (;;) {
assert(cio_poll(ctx, 100 * 1000) == 0);
struct cio_event *ev;
while ((ev = cio_iter(ctx))) {
switch (cioe_get_token(ev)) {
case TOKEN_LISTENER: {
struct cio_listener *listener = cioe_get_wrapper(ev);
if (cioe_is_readable(ev)) {
struct cio_stream *new_stream = cio_listener_accept(listener);
cio_register(ctx, cio_stream_getfd(new_stream), TOKEN_STREAM,
CIOF_READABLE | CIOF_WRITABLE, new_stream);
}
break;
}
case TOKEN_STREAM: {
struct cio_stream *stream = cioe_get_wrapper(ev);
if (cioe_is_readable(ev)) {
char buf[256] = {0};
int nr = cio_stream_recv(stream, buf, sizeof(buf));
if (nr == 0 || nr == -1) {
cio_unregister(ctx, cio_stream_getfd(stream));
cio_stream_drop(stream);
} else if (cioe_is_writable(ev)) {
cio_stream_send(stream, buf, nr);
}
}
break;
}
}
}
}
cio_unregister(ctx, cio_listener_getfd(listener));
cio_listener_drop(listener);
cio_drop(ctx);
To write a echo server in Rust.
// stream init
let tcp_server = cio::CioListener::bind("tcp://127.0.0.1:6000").expect("listen tcp failed");
let unix_server = cio::CioListener::bind("unix:///tmp/cio").expect("listen unix failed");
let com_conn = cio::CioStream::connect(
"com:///dev/ttyUSB0?baud=115200&data_bit=8&stop_bit=1&parity=N")
.expect("connect com failed");
// cio init
let ctx = cio::Cio::new().unwrap();
ctx.register(&tcp_server, tcp_server.fd, cio::CioFlag::READABLE);
ctx.register(&unix_server, unix_server.fd, cio::CioFlag::READABLE);
ctx.register(&com_conn, com_conn.fd, cio::CioFlag::READABLE | cio::CioFlag::WRITABLE);
// accepted streams init
let mut streams: HashMap<i32, cio::CioStream> = HashMap::new();
streams.insert(com_conn.fd, com_conn);
loop {
assert!(ctx.poll(100 * 1000) != -1);
while let Some(ev) = ctx.cio_iter() {
match ev.get_token() {
x if x == tcp_server.fd => {
if ev.is_readable() {
let new_stream = tcp_server.accept().expect("accept failed");
ctx.register(&new_stream, new_stream.fd,
cio::CioFlag::READABLE | cio::CioFlag::WRITABLE);
streams.insert(new_stream.fd, new_stream);
}
},
x if x == unix_server.fd => {
if ev.is_readable() {
let new_stream = unix_server.accept().expect("accept failed");
ctx.register(&new_stream, new_stream.fd,
cio::CioFlag::READABLE | cio::CioFlag::WRITABLE);
streams.insert(new_stream.fd, new_stream);
}
},
_ => {
if ev.is_readable() {
if let Some(stream) = streams.get(&ev.get_token()) {
let mut buf: [u8;256] = [0;256];
let nr = stream.recv(&mut buf);
if nr == 0 || nr == -1 {
ctx.unregister(&streams.remove(&ev.get_token()).unwrap());
} else if ev.is_writable() {
stream.send(&buf);
}
}
}
},
}
}
}
Lightweight stream based io framework.
- Linux
- MacOS
- MinGW
mkdir build && cd build
cmake ..
make && make install